@wokki20/jspt 2.0.4 → 2.0.5

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 CHANGED
@@ -15,12 +15,17 @@ Get started in seconds with our CDN:
15
15
  <html>
16
16
  <head>
17
17
  <!-- JSPT CSS -->
18
- <link rel="stylesheet" href="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.css">
18
+ <link rel="stylesheet" href="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.css">
19
19
  <!-- JSPT JavaScript -->
20
- <script src="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.min.js"></script>
20
+ <script src="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.min.js"></script>
21
21
  </head>
22
22
  <body>
23
23
  <script>
24
+ // Import icon libraries (required for classic scripts)
25
+ jspt.importScript({
26
+ names: ['material_symbols_rounded']
27
+ });
28
+
24
29
  // Show a toast notification
25
30
  jspt.makeToast({
26
31
  message: "Hello World!",
@@ -74,15 +79,22 @@ See [FOLDER_STRUCTURE.md](FOLDER_STRUCTURE.md) for detailed information.
74
79
  #### Production (Pinned Version - Stable)
75
80
  ```html
76
81
  <!-- CSS -->
77
- <link rel="stylesheet" href="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.css">
82
+ <link rel="stylesheet" href="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.css">
78
83
 
79
84
  <!-- JavaScript (minified) -->
80
- <script src="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.min.js"></script>
85
+ <script src="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.min.js"></script>
81
86
 
82
87
  <!-- Usage -->
83
88
  <script>
89
+ // Import icon libraries (required for classic scripts when using icons)
90
+ jspt.importScript({
91
+ names: ['material_symbols_rounded']
92
+ });
93
+
84
94
  jspt.makeToast({
85
- message: "Hello from CDN!"
95
+ message: "Hello from CDN!",
96
+ icon_left: "check_circle",
97
+ icon_left_type: "google_material_rounded"
86
98
  });
87
99
  </script>
88
100
  ```
@@ -96,25 +108,37 @@ jspt.makeToast({
96
108
 
97
109
  #### ES Module from CDN
98
110
  ```html
99
- <link rel="stylesheet" href="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.css">
111
+ <link rel="stylesheet" href="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.css">
100
112
 
101
113
  <script type="module">
102
- import { makeToast, makePopup } from 'https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.module.js';
114
+ import { makeToast, makePopup } from 'https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.module.js';
103
115
 
104
116
  makeToast({ message: "ES Module from CDN!" });
105
117
  </script>
106
118
  ```
107
119
 
120
+ **Note:** When using ES modules, you must manually include icon libraries in your HTML if needed:
121
+ ```html
122
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded">
123
+ ```
124
+
108
125
  ### Option 2: Download and Self-Host
109
126
 
110
- #### Script Tag (Traditional)
127
+ #### Script Tag (Classic Script)
111
128
  ```html
112
129
  <link rel="stylesheet" href="dist/jspt.css">
113
130
  <script src="dist/jspt.js"></script>
114
131
 
115
132
  <script>
133
+ // Import icon libraries first (required for classic scripts when using icons)
134
+ jspt.importScript({
135
+ names: ['material_symbols_rounded']
136
+ });
137
+
116
138
  jspt.makeToast({
117
- message: "Hello World!"
139
+ message: "Hello World!",
140
+ icon_left: "check_circle",
141
+ icon_left_type: "google_material_rounded"
118
142
  });
119
143
  </script>
120
144
  ```
@@ -134,12 +158,47 @@ makeToast({
134
158
  });
135
159
  ```
136
160
 
161
+ **Note:** For ES modules, manually include icon libraries in your HTML:
162
+ ```html
163
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded">
164
+ ```
165
+
137
166
  ### Option 3: NPM Package
138
167
 
139
168
  ```bash
140
169
  npm install @wokki20/jspt
141
170
  ```
142
171
 
172
+ ## Icon Libraries
173
+
174
+ ### Classic Scripts (Regular `<script>` tag)
175
+
176
+ When using JSPT with classic scripts, you **must** call `jspt.importScript()` to load icon libraries:
177
+
178
+ ```javascript
179
+ jspt.importScript({
180
+ names: ['material_symbols_rounded', 'material_symbols_outlined', 'lucide']
181
+ });
182
+ ```
183
+
184
+ **Available icon libraries:**
185
+ - `'material_symbols_rounded'` - Google Material Symbols (Rounded)
186
+ - `'material_symbols_outlined'` - Google Material Symbols (Outlined)
187
+ - `'lucide'` - Lucide Icons
188
+ - `'highlightjs'` - Highlight.js (for code syntax highlighting)
189
+
190
+ ### ES Modules
191
+
192
+ When using ES modules, `jspt.importScript()` is not available. You must manually include icon libraries in your HTML:
193
+
194
+ ```html
195
+ <!-- Material Symbols -->
196
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded">
197
+
198
+ <!-- Lucide Icons -->
199
+ <script src="https://unpkg.com/lucide@latest"></script>
200
+ ```
201
+
143
202
  ## CDN Usage
144
203
 
145
204
  JSPT is hosted on `https://cdn.wokki20.nl` with two delivery methods:
@@ -149,20 +208,20 @@ JSPT is hosted on `https://cdn.wokki20.nl` with two delivery methods:
149
208
  Use specific versions for stability and caching:
150
209
 
151
210
  ```html
152
- <!-- v2.0.4 - Minified (10KB) -->
153
- <script src="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.min.js"></script>
211
+ <!-- v2.0.5 - Minified (10KB) -->
212
+ <script src="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.min.js"></script>
154
213
 
155
- <!-- v2.0.4 - Full with JSDoc (24KB) -->
156
- <script src="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.js"></script>
214
+ <!-- v2.0.5 - Full with JSDoc (24KB) -->
215
+ <script src="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.js"></script>
157
216
 
158
- <!-- v2.0.4 - ES Module (21KB) -->
159
- <script type="module" src="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.module.js"></script>
217
+ <!-- v2.0.5 - ES Module (21KB) -->
218
+ <script type="module" src="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.module.js"></script>
160
219
 
161
220
  <!-- CSS -->
162
- <link rel="stylesheet" href="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.css">
221
+ <link rel="stylesheet" href="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.css">
163
222
 
164
223
  <!-- TypeScript Definitions -->
165
- /// <reference path="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.d.ts" />
224
+ /// <reference path="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.d.ts" />
166
225
  ```
167
226
 
168
227
  ✅ **Benefits:**
@@ -202,11 +261,11 @@ Always get the newest version automatically:
202
261
 
203
262
  | Use Case | Recommended URL |
204
263
  |----------|----------------|
205
- | Production website | `content/jspt-v2.0.4/jspt.min.js` (versioned) |
264
+ | Production website | `content/jspt-v2.0.5/jspt.min.js` (versioned) |
206
265
  | Testing/Development | `dynamic/jspt/jspt.js` (dynamic) |
207
- | Maximum performance | `content/jspt-v2.0.4/jspt.min.js` (minified + cached) |
208
- | ES6 Projects | `content/jspt-v2.0.4/jspt.module.js` (versioned module) |
209
- | TypeScript Projects | `content/jspt-v2.0.4/jspt.d.ts` (type definitions) |
266
+ | Maximum performance | `content/jspt-v2.0.5/jspt.min.js` (minified + cached) |
267
+ | ES6 Projects | `content/jspt-v2.0.5/jspt.module.js` (versioned module) |
268
+ | TypeScript Projects | `content/jspt-v2.0.5/jspt.d.ts` (type definitions) |
210
269
 
211
270
  ## Usage
212
271
 
@@ -223,6 +282,11 @@ jspt.makeToast({
223
282
  #### Toast with Icon
224
283
 
225
284
  ```javascript
285
+ // For classic scripts, import icons first
286
+ jspt.importScript({
287
+ names: ['material_symbols_rounded']
288
+ });
289
+
226
290
  jspt.makeToast({
227
291
  message: "Success!",
228
292
  style: "default",
@@ -285,6 +349,29 @@ jspt.makePopup({
285
349
 
286
350
  ## API Reference
287
351
 
352
+ ### `jspt.importScript(options)`
353
+
354
+ **(Classic scripts only)** Loads external libraries like icon fonts or syntax highlighters.
355
+
356
+ **Options:**
357
+
358
+ | Property | Type | Description |
359
+ |----------|------|-------------|
360
+ | `names` | string[] | Array of library names to import |
361
+
362
+ **Available libraries:**
363
+ - `'highlightjs'` - Highlight.js for code syntax highlighting
364
+ - `'material_symbols_rounded'` - Google Material Symbols (Rounded)
365
+ - `'material_symbols_outlined'` - Google Material Symbols (Outlined)
366
+ - `'lucide'` - Lucide Icons
367
+
368
+ **Example:**
369
+ ```javascript
370
+ jspt.importScript({
371
+ names: ['material_symbols_rounded', 'lucide', 'highlightjs']
372
+ });
373
+ ```
374
+
288
375
  ### `jspt.makeToast(options)`
289
376
 
290
377
  Creates a toast notification.
@@ -313,6 +400,7 @@ Creates a toast notification.
313
400
  - `'image'` - Image URL
314
401
  - `'text'` - Plain text
315
402
  - `'emoji'` - Emoji characters
403
+ - `'lucide_icon'` - Lucide Icons
316
404
 
317
405
  ### `jspt.makePopup(options)`
318
406
 
@@ -375,12 +463,9 @@ The TypeScript definitions are automatically picked up when you import the modul
375
463
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
376
464
  <title>JSPT CDN Example</title>
377
465
 
378
- <!-- Optional: Material Icons for icon support -->
379
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded">
380
-
381
466
  <!-- JSPT from CDN -->
382
- <link rel="stylesheet" href="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.css">
383
- <script src="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.min.js"></script>
467
+ <link rel="stylesheet" href="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.css">
468
+ <script src="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.min.js"></script>
384
469
  </head>
385
470
  <body>
386
471
  <h1>JSPT Example</h1>
@@ -388,6 +473,10 @@ The TypeScript definitions are automatically picked up when you import the modul
388
473
  <button onclick="showPopup()">Show Popup</button>
389
474
 
390
475
  <script>
476
+ jspt.importScript({
477
+ names: ['material_symbols_rounded']
478
+ });
479
+
391
480
  function showToast() {
392
481
  jspt.makeToast({
393
482
  message: "Hello from CDN!",
@@ -420,7 +509,6 @@ See `examples/example-script.html` for a full working example.
420
509
  <html>
421
510
  <head>
422
511
  <link rel="stylesheet" href="dist/jspt.css">
423
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded">
424
512
  </head>
425
513
  <body>
426
514
  <button onclick="showToast()">Show Toast</button>
@@ -428,6 +516,10 @@ See `examples/example-script.html` for a full working example.
428
516
 
429
517
  <script src="dist/jspt.js"></script>
430
518
  <script>
519
+ jspt.importScript({
520
+ names: ['material_symbols_rounded']
521
+ });
522
+
431
523
  function showToast() {
432
524
  jspt.makeToast({
433
525
  message: "Hello World!",
@@ -458,19 +550,22 @@ See `examples/example-script.html` for a full working example.
458
550
  <!DOCTYPE html>
459
551
  <html>
460
552
  <head>
461
- <link rel="stylesheet" href="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.css">
553
+ <link rel="stylesheet" href="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.css">
554
+ <!-- Manually include icon libraries for ES modules -->
555
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded">
462
556
  </head>
463
557
  <body>
464
558
  <button id="myButton">Show Toast</button>
465
559
  <button id="errorButton">Show Error</button>
466
560
 
467
561
  <script type="module">
468
- import { makeToast } from 'https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.module.js';
562
+ import { makeToast } from 'https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.module.js';
469
563
 
470
564
  document.getElementById('myButton').addEventListener('click', () => {
471
565
  makeToast({
472
566
  message: "Button clicked!",
473
567
  icon_left: "check",
568
+ icon_left_type: "google_material_rounded",
474
569
  duration: 2000
475
570
  });
476
571
  });
@@ -480,6 +575,7 @@ See `examples/example-script.html` for a full working example.
480
575
  style: "default-error",
481
576
  message: "Something went wrong",
482
577
  icon_left: "error",
578
+ icon_left_type: "google_material_rounded",
483
579
  duration: -1,
484
580
  close_on_click: true
485
581
  });
@@ -535,8 +631,8 @@ The library uses CSS custom properties for easy customization. You can override
535
631
  - ✅ **Pin to specific version** - Avoid unexpected breaking changes
536
632
  - ✅ **Preload for faster loading:**
537
633
  ```html
538
- <link rel="preload" href="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.min.js" as="script">
539
- <link rel="preload" href="https://cdn.wokki20.nl/content/jspt-v2.0.4/jspt.css" as="style">
634
+ <link rel="preload" href="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.min.js" as="script">
635
+ <link rel="preload" href="https://cdn.wokki20.nl/content/jspt-v2.0.5/jspt.css" as="style">
540
636
  ```
541
637
 
542
638
  ### File Sizes
@@ -585,9 +681,9 @@ MIT - See [LICENSE](LICENSE) file for details.
585
681
 
586
682
  ### Quick Links
587
683
  - [Installation Guide](#installation)
684
+ - [Icon Libraries](#icon-libraries)
588
685
  - [CDN Usage](#cdn-usage)
589
686
  - [API Reference](#api-reference)
590
687
  - [Examples](#examples)
591
688
  - [Contributing Guide](CONTRIBUTING.md)
592
- - [Changelog](CHANGELOG.md)
593
-
689
+ - [Changelog](CHANGELOG.md)
package/dist/jspt.css CHANGED
@@ -73,6 +73,11 @@
73
73
  color: #fff;
74
74
  }
75
75
 
76
+ .toast-container .toast .toast-icon.lucide {
77
+ width: 20px;
78
+ height: 20px;
79
+ }
80
+
76
81
  .toast-container .toast .toast-icon.toast-icon-image {
77
82
  width: 20px;
78
83
  height: 20px;
package/dist/jspt.d.ts CHANGED
@@ -14,10 +14,10 @@ export interface ToastOptions {
14
14
  message: string;
15
15
  custom_id?: string;
16
16
  icon_left?: string;
17
- icon_left_type?: 'google_material_rounded' | 'google_material_outlined' | 'svg' | 'image' | 'text' | 'emoji';
17
+ icon_left_type?: 'google_material_rounded' | 'google_material_outlined' | 'svg' | 'image' | 'text' | 'emoji' | 'lucide_icon';
18
18
  icon_left_action?: () => void;
19
19
  icon_right?: string;
20
- icon_right_type?: 'google_material_rounded' | 'google_material_outlined' | 'svg' | 'image' | 'text' | 'emoji';
20
+ icon_right_type?: 'google_material_rounded' | 'google_material_outlined' | 'svg' | 'image' | 'text' | 'emoji' | 'lucide_icon';
21
21
  icon_right_action?: () => void;
22
22
  duration?: number;
23
23
  close_on_click?: boolean;
@@ -28,16 +28,23 @@ export interface ClosePopupOptions {
28
28
  custom_id: string;
29
29
  }
30
30
 
31
+ export interface ImportScripts {
32
+ names: Array <'highlightjs' | 'material_symbols_rounded' | 'material_symbols_outlined' | 'lucide'>;
33
+ };
34
+
31
35
  export function makePopup(options: PopupOptions): void;
32
36
 
33
37
  export function makeToast(options: ToastOptions): void;
34
38
 
35
39
  export function closePopup(options: ClosePopupOptions): void;
36
40
 
41
+ export function importScripts(options: ImportScripts): void;
42
+
37
43
  declare const jspt: {
38
44
  makePopup: typeof makePopup;
39
45
  makeToast: typeof makeToast;
40
46
  closePopup: typeof closePopup;
47
+ importScripts: typeof importScripts;
41
48
  };
42
49
 
43
50
  export default jspt;
package/dist/jspt.js CHANGED
@@ -21,28 +21,63 @@
21
21
  * @property {string} message
22
22
  * @property {string} [custom_id]
23
23
  * @property {string} [icon_left]
24
- * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'} [icon_left_type='google_material_rounded']
24
+ * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'|'lucide_icon'} [icon_left_type='google_material_rounded']
25
25
  * @property {Function} [icon_left_action]
26
26
  * @property {string} [icon_right]
27
- * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'} [icon_right_type='google_material_rounded']
27
+ * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'|'lucide_icon'} [icon_right_type='google_material_rounded']
28
28
  * @property {Function} [icon_right_action]
29
29
  * @property {number} [duration=5000]
30
30
  * @property {boolean} [close_on_click=false]
31
31
  * @property {Function} [onclick]
32
32
  */
33
33
 
34
- let debugMode = false;
35
-
36
- const script = document.createElement('script');
37
- script.src = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js';
38
- document.head.appendChild(script);
34
+ /**
35
+ * @typedef {Object} ImportScript
36
+ * @property {Array<'highlightjs'|'material_symbols_rounded'|'material_symbols_outlined'|'lucide'>} names
37
+ */
39
38
 
40
- const link = document.createElement('link');
41
- link.rel = 'stylesheet';
42
- link.href = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css';
43
- document.head.appendChild(link);
39
+ let debugMode = false;
44
40
 
45
41
  const jspt = {
42
+ /**
43
+ * @param {ImportScript} options
44
+ * @returns {void}
45
+ */
46
+ importScript: function(options) {
47
+ const { names } = options;
48
+ names.forEach(name => {
49
+ switch (name) {
50
+ case 'highlightjs':
51
+ const hljs = document.createElement('script');
52
+ hljs.src = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js';
53
+ document.head.appendChild(hljs);
54
+
55
+ const link = document.createElement('link');
56
+ link.rel = 'stylesheet';
57
+ link.href = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css';
58
+ document.head.appendChild(link);
59
+ break;
60
+ case 'material_symbols_rounded':
61
+ const msr = document.createElement('link');
62
+ msr.rel = 'stylesheet';
63
+ msr.href = 'https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200';
64
+ document.head.appendChild(msr);
65
+ break;
66
+ case 'material_symbols_outlined':
67
+ const mso = document.createElement('link');
68
+ mso.rel = 'stylesheet';
69
+ mso.href = 'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200';
70
+ document.head.appendChild(mso);
71
+ break;
72
+ case 'lucide':
73
+ const lucide = document.createElement('script');
74
+ lucide.src = 'https://unpkg.com/lucide@latest';
75
+ document.head.appendChild(lucide);
76
+ break;
77
+ }
78
+ });
79
+ },
80
+
46
81
  /**
47
82
  * @param {ClosePopupOptions} options
48
83
  * @returns {void}
@@ -366,6 +401,9 @@ const jspt = {
366
401
  case 'emoji':
367
402
  iconLeftElement.innerText = icon_left;
368
403
  break;
404
+ case 'lucide_icon':
405
+ iconLeftElement.dataset.lucide = icon_left;
406
+ break;
369
407
  }
370
408
 
371
409
  toast.appendChild(iconLeftElement);
@@ -414,6 +452,9 @@ const jspt = {
414
452
  case 'emoji':
415
453
  iconRightElement.innerText = icon_right;
416
454
  break;
455
+ case 'lucide_icon':
456
+ iconRightElement.dataset.lucide = icon_right;
457
+ break;
417
458
  }
418
459
 
419
460
  toast.appendChild(iconRightElement);
@@ -581,6 +622,7 @@ const jspt = {
581
622
 
582
623
  const mo = new MutationObserver(updateToasts);
583
624
  mo.observe(container, { childList: true });
625
+ if (typeof lucide !== 'undefined') lucide.createIcons();
584
626
  }
585
627
  };
586
628
 
package/dist/jspt.min.js CHANGED
@@ -1 +1 @@
1
- let debugMode=false;const script=document.createElement("script");script.src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js";document.head.appendChild(script);const link=document.createElement("link");link.rel="stylesheet";link.href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css";document.head.appendChild(link);const jspt={closePopup:function(options){const{custom_id:custom_id}=options;const popup=document.querySelector(`.popup-container#${custom_id}`);if(popup){popup.remove()}},makePopup:function(options){const{style:style="default",content_type:content_type="text",header:header,title:title,message:message,content:content,close_on_blur:close_on_blur=true,custom_id:custom_id=Math.random().toString(36).substring(2)}=options;const sanitize=input=>input.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;");const createErrorPopupContent=(lineNumber,error_message)=>fetch(location.href).then(res=>res.text()).then(code=>{const lines=code.split("\n");const start=Math.max(0,lineNumber-3);const end=Math.min(lines.length,lineNumber+10);const snippetLines=lines.slice(start,end);while(snippetLines.length&&snippetLines[snippetLines.length-1].trim()===""){snippetLines.pop()}const snippet=snippetLines.map((line,i)=>{const actualLine=start+i+1;if(!/\S/.test(line))return"";const leadingSpaces=line.match(/^\s*/)[0].replace(/ /g,"&nbsp;").replace(/\t/g,"&nbsp;&nbsp;&nbsp;&nbsp;");const highlighted=hljs.highlight(line.trimStart(),{language:"javascript"}).value;if(actualLine===lineNumber){return`<span class="popup-error-code-line popup-error-code-line-highlight"><span class="popup-error-code-line-number">${actualLine}</span>${leadingSpaces}${highlighted}</span>`}return`<span class="popup-error-code-line"><span class="popup-error-code-line-number">${actualLine}</span>${leadingSpaces}${highlighted}</span>`}).join("");return`\n <p>${error_message}</p>\n <pre class="popup-error-code">\n <div class="popup-error-code-header"><p class="popup-error-code-header-file">${location.href.split("/").pop().split("?")[0]}</p></div>\n <code class="hljs language-javascript">${snippet}</code>\n </pre>\n `}).catch(err=>{console.error("Failed to fetch source:",err);return`<p>Failed to fetch source code</p>`});const popup=document.createElement("div");popup.classList.add("popup");if(content_type==="text"){if(content){const err=new Error;const stackLines=err.stack.split("\n");const callerLine=stackLines[2]||"";const lineMatch=callerLine.match(/:(\d+):\d+\)?$/);const lineNumber=lineMatch?parseInt(lineMatch[1]):null;const errorMsg=`Error on line ${lineNumber}: Cannot use content when content_type is text in jspt.makePopup(), Please make sure content is not provided`;if(lineNumber){createErrorPopupContent(lineNumber,errorMsg).then(popupContent=>{jspt.makeToast({style:"default-error",message:errorMsg,duration:-1,close_on_click:true,icon_left:"unknown_document",icon_left_type:"google_material_rounded",icon_left_action:()=>{jspt.makePopup({content_type:"html",header:"Error",content:popupContent})}})})}else{jspt.makeToast({style:"default-error",message:errorMsg,duration:-1,close_on_click:true})}}}else if(content_type==="html"){if(message){const stackLines=(new Error).stack.split("\n");const callerLine=stackLines[2]||"";const lineMatch=callerLine.match(/:(\d+):\d+\)?$/);const lineNumber=lineMatch?parseInt(lineMatch[1]):null;const errorMsg=`Error on line ${lineNumber}: Cannot use message when content_type is html in jspt.makePopup(), Please make sure message is not provided`;if(lineNumber){createErrorPopupContent(lineNumber,errorMsg).then(popupContent=>{jspt.makeToast({style:"default-error",message:errorMsg,duration:-1,close_on_click:true,icon_left:"unknown_document",icon_left_type:"google_material_rounded",icon_left_action:()=>{jspt.makePopup({content_type:"html",header:"Error",content:popupContent})}})})}else{jspt.makeToast({style:"default-error",message:errorMsg,duration:-1,close_on_click:true})}}if(title){const stackLines=(new Error).stack.split("\n");const callerLine=stackLines[2]||"";const lineMatch=callerLine.match(/:(\d+):\d+\)?$/);const lineNumber=lineMatch?parseInt(lineMatch[1]):null;const errorMsg=`Error on line ${lineNumber}: Cannot use title when content_type is html in jspt.makePopup(), Please make sure title is not provided`;if(lineNumber){createErrorPopupContent(lineNumber,errorMsg).then(popupContent=>{jspt.makeToast({style:"default-error",message:errorMsg,duration:-1,close_on_click:true,icon_left:"unknown_document",icon_left_type:"google_material_rounded",icon_left_action:()=>{jspt.makePopup({content_type:"html",header:"Error",content:popupContent})}})})}else{jspt.makeToast({style:"default-error",message:errorMsg,duration:-1,close_on_click:true})}}}const popupHeader=document.createElement("div");popupHeader.classList.add("popup-header");const popupHeaderTitle=document.createElement("p");popupHeaderTitle.innerText=header||"";popupHeader.appendChild(popupHeaderTitle);const popupHeaderClose=document.createElement("span");popupHeaderClose.classList.add("popup-header-close");popupHeaderClose.innerHTML="&times;";popupHeaderClose.addEventListener("click",()=>{popupContainer.remove()});popupHeader.appendChild(popupHeaderClose);popup.appendChild(popupHeader);const popupContent=document.createElement("div");popupContent.classList.add("popup-content");if(content_type==="text"){if(title){const popupTitle=document.createElement("h3");popupTitle.innerText=title;popupContent.appendChild(popupTitle)}if(message){const popupMessage=document.createElement("p");popupMessage.innerText=message;popupContent.appendChild(popupMessage)}}else if(content_type==="html"){popupContent.innerHTML=content||""}popup.appendChild(popupContent);const popupContainer=document.createElement("div");popupContainer.classList.add("popup-container");popupContainer.appendChild(popup);popupContainer.id=custom_id;if(close_on_blur){popupContainer.addEventListener("click",e=>{if(e.target===popupContainer){popupContainer.remove()}})}document.body.appendChild(popupContainer)},makeToast:function(options){const{style:style="default",message:message,custom_id:custom_id,icon_left:icon_left,icon_left_type:icon_left_type="google_material_rounded",icon_left_action:icon_left_action,icon_right:icon_right,icon_right_type:icon_right_type="google_material_rounded",icon_right_action:icon_right_action,duration:duration=5e3,close_on_click:close_on_click=false,onclick:onclick}=options;let container=document.querySelector(".toast-container");if(!container){container=document.createElement("div");container.classList.add("toast-container");document.body.appendChild(container)}const existingToast=custom_id?document.getElementById(custom_id):null;if(existingToast){existingToast.remove()}const toast=document.createElement("div");toast.classList.add("toast");if(custom_id)toast.id=custom_id;if(style.startsWith("toast-")){toast.classList.add(style)}else{toast.classList.add(`toast-${style}`)}if(icon_left){const iconLeftElement=document.createElement("span");iconLeftElement.classList.add("toast-icon");if(icon_left_action){iconLeftElement.classList.add("action");iconLeftElement.style.setProperty("--cursor","pointer");iconLeftElement.addEventListener("click",e=>{e.stopPropagation();icon_left_action()})}switch(icon_left_type){case"google_material_rounded":iconLeftElement.classList.add("material-symbols-rounded");iconLeftElement.innerText=icon_left;break;case"google_material_outlined":iconLeftElement.classList.add("material-symbols-outlined");iconLeftElement.innerText=icon_left;break;case"svg":iconLeftElement.innerHTML=icon_left;break;case"image":const img=document.createElement("img");img.src=icon_left;img.classList.add("toast-icon-image");if(icon_left_action)img.classList.add("action");iconLeftElement.appendChild(img);break;case"text":iconLeftElement.innerText=icon_left;break;case"emoji":iconLeftElement.innerText=icon_left;break}toast.appendChild(iconLeftElement)}const toastText=document.createElement("span");toastText.classList.add("toast-text");toastText.innerHTML=message;toast.appendChild(toastText);if(icon_right){const iconRightElement=document.createElement("span");iconRightElement.classList.add("toast-icon");if(icon_right_action){iconRightElement.classList.add("action");iconRightElement.style.setProperty("--cursor","pointer");iconRightElement.addEventListener("click",e=>{e.stopPropagation();icon_right_action()})}switch(icon_right_type){case"google_material_rounded":iconRightElement.classList.add("material-symbols-rounded");iconRightElement.innerText=icon_right;break;case"google_material_outlined":iconRightElement.classList.add("material-symbols-outlined");iconRightElement.innerText=icon_right;break;case"svg":iconRightElement.innerHTML=icon_right;break;case"image":const img=document.createElement("img");img.src=icon_right;img.classList.add("toast-icon-image");if(icon_right_action)img.classList.add("action");iconRightElement.appendChild(img);break;case"text":iconRightElement.innerText=icon_right;break;case"emoji":iconRightElement.innerText=icon_right;break}toast.appendChild(iconRightElement)}if(duration>0){const toastDurationBar=document.createElement("div");toastDurationBar.classList.add("toast-duration-bar");toast.appendChild(toastDurationBar);setTimeout(()=>{toastDurationBar.style.width="100%";toastDurationBar.style.transition=`width ${duration}ms linear`},10);setTimeout(()=>{removeToast(toast)},duration)}if(close_on_click){toast.style.setProperty("--cursor","pointer");toast.addEventListener("click",e=>{if(e.target.classList.contains("action"))return;removeToast(toast)})}container.appendChild(toast);if(onclick){toast.style.setProperty("--cursor","pointer");toast.addEventListener("click",e=>{if(e.target.classList.contains("action"))return;onclick();updateToasts();container.dispatchEvent(new CustomEvent("mouseleave"))})}function updateToasts(){const toasts=Array.from(container.querySelectorAll(".toast"));if(!toasts.length)return;const cs=getComputedStyle(container);const gap=parseFloat(cs.gap||cs.rowGap||"0")||0;const originalHeights=toasts.map(t=>t.getBoundingClientRect().height);const lastIndex=toasts.length-1;toasts.forEach((t,i)=>{t.style.zIndex=String(100+i);t.classList.remove("stacked")});if(toasts.length===1){toasts[0].style.setProperty("--translate","0px");return}for(let i=0;i<toasts.length;i++){const toast=toasts[i];if(i===lastIndex){toast.style.setProperty("--translate","0px")}else if(i===lastIndex-1){const translate=originalHeights[i]+gap-5;toast.style.setProperty("--translate",`${translate}px`);toast.style.setProperty("--scale","0.97");toast.classList.add("stacked")}else{let delta=0;for(let k=i;k<=lastIndex-1;k++){delta+=originalHeights[k]+gap-2}toast.style.setProperty("--translate",`${delta}px`);toast.style.setProperty("--scale","0.97");toast.classList.add("stacked")}}}function removeToast(toast){const toasts=Array.from(container.querySelectorAll(".toast"));const index=toasts.indexOf(toast);const toastRects=toasts.map(t=>t.getBoundingClientRect());toasts.forEach((el,i)=>{if(i<index){el.style.transition="transform 0.25s ease";el.style.transform=`translateY(${toastRects[index].height+8}px)`}});toast.style.transition="transform 0.25s ease, opacity 0.25s ease";toast.style.transform=`translateX(100%)`;toast.style.opacity="0";toast.addEventListener("transitionend",()=>{toast.remove();toasts.forEach(el=>{el.style.transition="";el.style.transform=""})},{once:true})}let toastTimeout;function expandToastsOnContainerHover(container){const toasts=Array.from(container.querySelectorAll(".toast"));const expandedHeights=toasts.map(toast=>{const clone=toast.cloneNode(true);clone.style.position="absolute";clone.style.visibility="hidden";clone.style.height="auto";clone.style.whiteSpace="normal";clone.style.overflow="visible";clone.style.textOverflow="unset";clone.style.wordBreak="break-word";container.appendChild(clone);const height=clone.offsetHeight;container.removeChild(clone);return height});const expandAll=()=>{toasts.forEach((toast,i)=>{const textHeight=toast.querySelector(".toast-text").scrollHeight;const height=textHeight>expandedHeights[i]?expandedHeights[i]+20:expandedHeights[i]-20;toast.style.height=`${height}px`})};const resetAll=()=>{toasts.forEach(toast=>toast.style.height="")};container.addEventListener("mouseenter",()=>{if(toastTimeout){clearTimeout(toastTimeout);toastTimeout=null}expandAll()});container.addEventListener("mouseleave",()=>{resetAll();if(toastTimeout){clearTimeout(toastTimeout)}toastTimeout=setTimeout(()=>{toastTimeout=null},300)})}expandToastsOnContainerHover(container);updateToasts();window.addEventListener("resize",updateToasts);const mo=new MutationObserver(updateToasts);mo.observe(container,{childList:true})}};const currentScript=document.currentScript;const params=currentScript?new URL(currentScript.src).searchParams:new URLSearchParams;window.addEventListener("DOMContentLoaded",()=>{if(params.get("debug")==="true"){debugMode=true;if(currentScript&&!currentScript.src.includes("https://cdn.wokki20.nl/content")){console.log("Debug mode disabled.");console.log("This script is not hosted on cdn.wokki20.nl, debug mode is disabled. Please use https://cdn.wokki20.nl/content/jspt_latest/jspt.js instead.");console.log("If you are hosting this script yourself, you can manually enable debug mode by changing debugMode to true in the script.");debugMode=false;if(typeof jspt!=="undefined"){jspt.makeToast({style:"default-error",message:"This script is not hosted on cdn.wokki20.nl, please check console for more information.",duration:-1,close_on_click:true})}return}console.log("Debug mode enabled");if(typeof jspt!=="undefined"){jspt.makeToast({style:"default",message:"Debug mode enabled, do not use in production",duration:-1,close_on_click:true})}}});if(typeof window!=="undefined"){window.jspt=jspt}
1
+ let debugMode=!1;const jspt={importScript:function(e){const{names:t}=e;t.forEach(e=>{switch(e){case"highlightjs":const e=document.createElement("script");e.src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js",document.head.appendChild(e);const t=document.createElement("link");t.rel="stylesheet",t.href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css",document.head.appendChild(t);break;case"material_symbols_rounded":const s=document.createElement("link");s.rel="stylesheet",s.href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200",document.head.appendChild(s);break;case"material_symbols_outlined":const n=document.createElement("link");n.rel="stylesheet",n.href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200",document.head.appendChild(n);break;case"lucide":const o=document.createElement("script");o.src="https://unpkg.com/lucide@latest",document.head.appendChild(o)}})},closePopup:function(e){const{custom_id:t}=e,s=document.querySelector(`.popup-container#${t}`);s&&s.remove()},makePopup:function(e){const{style:t="default",content_type:s="text",header:n,title:o,message:a,content:r,close_on_blur:c=!0,custom_id:i=Math.random().toString(36).substring(2)}=e,l=(e,t)=>fetch(location.href).then(e=>e.text()).then(s=>{const n=s.split("\n"),o=Math.max(0,e-3),a=Math.min(n.length,e+10),r=n.slice(o,a);for(;r.length&&""===r[r.length-1].trim();)r.pop();const c=r.map((t,s)=>{const n=o+s+1;if(!/\S/.test(t))return"";const a=t.match(/^\s*/)[0].replace(/ /g,"&nbsp;").replace(/\t/g,"&nbsp;&nbsp;&nbsp;&nbsp;"),r=hljs.highlight(t.trimStart(),{language:"javascript"}).value;return n===e?`<span class="popup-error-code-line popup-error-code-line-highlight"><span class="popup-error-code-line-number">${n}</span>${a}${r}</span>`:`<span class="popup-error-code-line"><span class="popup-error-code-line-number">${n}</span>${a}${r}</span>`}).join("");return`\n <p>${t}</p>\n <pre class="popup-error-code">\n <div class="popup-error-code-header"><p class="popup-error-code-header-file">${location.href.split("/").pop().split("?")[0]}</p></div>\n <code class="hljs language-javascript">${c}</code>\n </pre>\n `}).catch(e=>(console.error("Failed to fetch source:",e),"<p>Failed to fetch source code</p>")),d=document.createElement("div");if(d.classList.add("popup"),"text"===s){if(r){const e=((new Error).stack.split("\n")[2]||"").match(/:(\d+):\d+\)?$/),t=e?parseInt(e[1]):null,s=`Error on line ${t}: Cannot use content when content_type is text in jspt.makePopup(), Please make sure content is not provided`;t?l(t,s).then(e=>{jspt.makeToast({style:"default-error",message:s,duration:-1,close_on_click:!0,icon_left:"unknown_document",icon_left_type:"google_material_rounded",icon_left_action:()=>{jspt.makePopup({content_type:"html",header:"Error",content:e})}})}):jspt.makeToast({style:"default-error",message:s,duration:-1,close_on_click:!0})}}else if("html"===s){if(a){const e=((new Error).stack.split("\n")[2]||"").match(/:(\d+):\d+\)?$/),t=e?parseInt(e[1]):null,s=`Error on line ${t}: Cannot use message when content_type is html in jspt.makePopup(), Please make sure message is not provided`;t?l(t,s).then(e=>{jspt.makeToast({style:"default-error",message:s,duration:-1,close_on_click:!0,icon_left:"unknown_document",icon_left_type:"google_material_rounded",icon_left_action:()=>{jspt.makePopup({content_type:"html",header:"Error",content:e})}})}):jspt.makeToast({style:"default-error",message:s,duration:-1,close_on_click:!0})}if(o){const e=((new Error).stack.split("\n")[2]||"").match(/:(\d+):\d+\)?$/),t=e?parseInt(e[1]):null,s=`Error on line ${t}: Cannot use title when content_type is html in jspt.makePopup(), Please make sure title is not provided`;t?l(t,s).then(e=>{jspt.makeToast({style:"default-error",message:s,duration:-1,close_on_click:!0,icon_left:"unknown_document",icon_left_type:"google_material_rounded",icon_left_action:()=>{jspt.makePopup({content_type:"html",header:"Error",content:e})}})}):jspt.makeToast({style:"default-error",message:s,duration:-1,close_on_click:!0})}}const p=document.createElement("div");p.classList.add("popup-header");const u=document.createElement("p");u.innerText=n||"",p.appendChild(u);const m=document.createElement("span");m.classList.add("popup-header-close"),m.innerHTML="&times;",m.addEventListener("click",()=>{g.remove()}),p.appendChild(m),d.appendChild(p);const h=document.createElement("div");if(h.classList.add("popup-content"),"text"===s){if(o){const e=document.createElement("h3");e.innerText=o,h.appendChild(e)}if(a){const e=document.createElement("p");e.innerText=a,h.appendChild(e)}}else"html"===s&&(h.innerHTML=r||"");d.appendChild(h);const g=document.createElement("div");g.classList.add("popup-container"),g.appendChild(d),g.id=i,c&&g.addEventListener("click",e=>{e.target===g&&g.remove()}),document.body.appendChild(g)},makeToast:function(e){const{style:t="default",message:s,custom_id:n,icon_left:o,icon_left_type:a="google_material_rounded",icon_left_action:r,icon_right:c,icon_right_type:i="google_material_rounded",icon_right_action:l,duration:d=5e3,close_on_click:p=!1,onclick:u}=e;let m=document.querySelector(".toast-container");m||(m=document.createElement("div"),m.classList.add("toast-container"),document.body.appendChild(m));const h=n?document.getElementById(n):null;h&&h.remove();const g=document.createElement("div");if(g.classList.add("toast"),n&&(g.id=n),t.startsWith("toast-")?g.classList.add(t):g.classList.add(`toast-${t}`),o){const e=document.createElement("span");switch(e.classList.add("toast-icon"),r&&(e.classList.add("action"),e.style.setProperty("--cursor","pointer"),e.addEventListener("click",e=>{e.stopPropagation(),r()})),a){case"google_material_rounded":e.classList.add("material-symbols-rounded"),e.innerText=o;break;case"google_material_outlined":e.classList.add("material-symbols-outlined"),e.innerText=o;break;case"svg":e.innerHTML=o;break;case"image":const t=document.createElement("img");t.src=o,t.classList.add("toast-icon-image"),r&&t.classList.add("action"),e.appendChild(t);break;case"text":case"emoji":e.innerText=o;break;case"lucide_icon":e.dataset.lucide=o}g.appendChild(e)}const y=document.createElement("span");if(y.classList.add("toast-text"),y.innerHTML=s,g.appendChild(y),c){const e=document.createElement("span");switch(e.classList.add("toast-icon"),l&&(e.classList.add("action"),e.style.setProperty("--cursor","pointer"),e.addEventListener("click",e=>{e.stopPropagation(),l()})),i){case"google_material_rounded":e.classList.add("material-symbols-rounded"),e.innerText=c;break;case"google_material_outlined":e.classList.add("material-symbols-outlined"),e.innerText=c;break;case"svg":e.innerHTML=c;break;case"image":const t=document.createElement("img");t.src=c,t.classList.add("toast-icon-image"),l&&t.classList.add("action"),e.appendChild(t);break;case"text":case"emoji":e.innerText=c;break;case"lucide_icon":e.dataset.lucide=c}g.appendChild(e)}if(d>0){const e=document.createElement("div");e.classList.add("toast-duration-bar"),g.appendChild(e),setTimeout(()=>{e.style.width="100%",e.style.transition=`width ${d}ms linear`},10),setTimeout(()=>{_(g)},d)}function f(){const e=Array.from(m.querySelectorAll(".toast"));if(!e.length)return;const t=getComputedStyle(m),s=parseFloat(t.gap||t.rowGap||"0")||0,n=e.map(e=>e.getBoundingClientRect().height),o=e.length-1;if(e.forEach((e,t)=>{e.style.zIndex=String(100+t),e.classList.remove("stacked")}),1!==e.length)for(let t=0;t<e.length;t++){const a=e[t];if(t===o)a.style.setProperty("--translate","0px");else if(t===o-1){const e=n[t]+s-5;a.style.setProperty("--translate",`${e}px`),a.style.setProperty("--scale","0.97"),a.classList.add("stacked")}else{let e=0;for(let a=t;a<=o-1;a++)e+=n[a]+s-2;a.style.setProperty("--translate",`${e}px`),a.style.setProperty("--scale","0.97"),a.classList.add("stacked")}}else e[0].style.setProperty("--translate","0px")}function _(e){const t=Array.from(m.querySelectorAll(".toast")),s=t.indexOf(e),n=t.map(e=>e.getBoundingClientRect());t.forEach((e,t)=>{t<s&&(e.style.transition="transform 0.25s ease",e.style.transform=`translateY(${n[s].height+8}px)`)}),e.style.transition="transform 0.25s ease, opacity 0.25s ease",e.style.transform="translateX(100%)",e.style.opacity="0",e.addEventListener("transitionend",()=>{e.remove(),t.forEach(e=>{e.style.transition="",e.style.transform=""})},{once:!0})}let k;p&&(g.style.setProperty("--cursor","pointer"),g.addEventListener("click",e=>{e.target.classList.contains("action")||_(g)})),m.appendChild(g),u&&(g.style.setProperty("--cursor","pointer"),g.addEventListener("click",e=>{e.target.classList.contains("action")||(u(),f(),m.dispatchEvent(new CustomEvent("mouseleave")))})),function(e){const t=Array.from(e.querySelectorAll(".toast")),s=t.map(t=>{const s=t.cloneNode(!0);s.style.position="absolute",s.style.visibility="hidden",s.style.height="auto",s.style.whiteSpace="normal",s.style.overflow="visible",s.style.textOverflow="unset",s.style.wordBreak="break-word",e.appendChild(s);const n=s.offsetHeight;return e.removeChild(s),n});e.addEventListener("mouseenter",()=>{k&&(clearTimeout(k),k=null),t.forEach((e,t)=>{const n=e.querySelector(".toast-text").scrollHeight>s[t]?s[t]+20:s[t]-20;e.style.height=`${n}px`})}),e.addEventListener("mouseleave",()=>{t.forEach(e=>e.style.height=""),k&&clearTimeout(k),k=setTimeout(()=>{k=null},300)})}(m),f(),window.addEventListener("resize",f);new MutationObserver(f).observe(m,{childList:!0}),"undefined"!=typeof lucide&&lucide.createIcons()}},currentScript=document.currentScript,params=currentScript?new URL(currentScript.src).searchParams:new URLSearchParams;window.addEventListener("DOMContentLoaded",()=>{if("true"===params.get("debug")){if(debugMode=!0,currentScript&&!currentScript.src.includes("https://cdn.wokki20.nl/content"))return console.log("Debug mode disabled."),console.log("This script is not hosted on cdn.wokki20.nl, debug mode is disabled. Please use https://cdn.wokki20.nl/content/jspt_latest/jspt.js instead."),console.log("If you are hosting this script yourself, you can manually enable debug mode by changing debugMode to true in the script."),debugMode=!1,void(void 0!==jspt&&jspt.makeToast({style:"default-error",message:"This script is not hosted on cdn.wokki20.nl, please check console for more information.",duration:-1,close_on_click:!0}));console.log("Debug mode enabled"),void 0!==jspt&&jspt.makeToast({style:"default",message:"Debug mode enabled, do not use in production",duration:-1,close_on_click:!0})}}),"undefined"!=typeof window&&(window.jspt=jspt);
@@ -1,3 +1,5 @@
1
+ import { createIcons, icons } from "https://esm.sh/lucide@0.564.0";
2
+
1
3
  /**
2
4
  * @typedef {Object} PopupOptions
3
5
  * @property {'default'} [style='default']
@@ -21,10 +23,10 @@
21
23
  * @property {string} message
22
24
  * @property {string} [custom_id]
23
25
  * @property {string} [icon_left]
24
- * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'} [icon_left_type='google_material_rounded']
26
+ * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'|'lucide_icon'} [icon_left_type='google_material_rounded']
25
27
  * @property {Function} [icon_left_action]
26
28
  * @property {string} [icon_right]
27
- * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'} [icon_right_type='google_material_rounded']
29
+ * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'|'lucide_icon'} [icon_right_type='google_material_rounded']
28
30
  * @property {Function} [icon_right_action]
29
31
  * @property {number} [duration=5000]
30
32
  * @property {boolean} [close_on_click=false]
@@ -388,6 +390,9 @@ export function makeToast(options) {
388
390
  case 'emoji':
389
391
  iconLeftElement.innerText = icon_left;
390
392
  break;
393
+ case 'lucide_icon':
394
+ iconLeftElement.dataset.lucide = icon_left;
395
+ break;
391
396
  }
392
397
 
393
398
  toast.appendChild(iconLeftElement);
@@ -436,6 +441,9 @@ export function makeToast(options) {
436
441
  case 'emoji':
437
442
  iconRightElement.innerText = icon_right;
438
443
  break;
444
+ case 'lucide_icon':
445
+ iconRightElement.dataset.lucide = icon_right;
446
+ break;
439
447
  }
440
448
 
441
449
  toast.appendChild(iconRightElement);
@@ -603,6 +611,7 @@ export function makeToast(options) {
603
611
 
604
612
  const mo = new MutationObserver(updateToasts);
605
613
  mo.observe(container, { childList: true });
614
+ createIcons({icons});
606
615
  }
607
616
 
608
617
  export default {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wokki20/jspt",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "description": "A modern JavaScript library for creating toast notifications and popups with error handling",
5
5
  "main": "dist/jspt.js",
6
6
  "module": "dist/jspt.module.js",
package/src/jspt.css CHANGED
@@ -73,6 +73,11 @@
73
73
  color: #fff;
74
74
  }
75
75
 
76
+ .toast-container .toast .toast-icon.lucide {
77
+ width: 20px;
78
+ height: 20px;
79
+ }
80
+
76
81
  .toast-container .toast .toast-icon.toast-icon-image {
77
82
  width: 20px;
78
83
  height: 20px;
package/src/jspt.d.ts CHANGED
@@ -14,10 +14,10 @@ export interface ToastOptions {
14
14
  message: string;
15
15
  custom_id?: string;
16
16
  icon_left?: string;
17
- icon_left_type?: 'google_material_rounded' | 'google_material_outlined' | 'svg' | 'image' | 'text' | 'emoji';
17
+ icon_left_type?: 'google_material_rounded' | 'google_material_outlined' | 'svg' | 'image' | 'text' | 'emoji' | 'lucide_icon';
18
18
  icon_left_action?: () => void;
19
19
  icon_right?: string;
20
- icon_right_type?: 'google_material_rounded' | 'google_material_outlined' | 'svg' | 'image' | 'text' | 'emoji';
20
+ icon_right_type?: 'google_material_rounded' | 'google_material_outlined' | 'svg' | 'image' | 'text' | 'emoji' | 'lucide_icon';
21
21
  icon_right_action?: () => void;
22
22
  duration?: number;
23
23
  close_on_click?: boolean;
@@ -28,16 +28,23 @@ export interface ClosePopupOptions {
28
28
  custom_id: string;
29
29
  }
30
30
 
31
+ export interface ImportScripts {
32
+ names: Array <'highlightjs' | 'material_symbols_rounded' | 'material_symbols_outlined' | 'lucide'>;
33
+ };
34
+
31
35
  export function makePopup(options: PopupOptions): void;
32
36
 
33
37
  export function makeToast(options: ToastOptions): void;
34
38
 
35
39
  export function closePopup(options: ClosePopupOptions): void;
36
40
 
41
+ export function importScripts(options: ImportScripts): void;
42
+
37
43
  declare const jspt: {
38
44
  makePopup: typeof makePopup;
39
45
  makeToast: typeof makeToast;
40
46
  closePopup: typeof closePopup;
47
+ importScripts: typeof importScripts;
41
48
  };
42
49
 
43
50
  export default jspt;
package/src/jspt.js CHANGED
@@ -21,28 +21,63 @@
21
21
  * @property {string} message
22
22
  * @property {string} [custom_id]
23
23
  * @property {string} [icon_left]
24
- * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'} [icon_left_type='google_material_rounded']
24
+ * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'|'lucide_icon'} [icon_left_type='google_material_rounded']
25
25
  * @property {Function} [icon_left_action]
26
26
  * @property {string} [icon_right]
27
- * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'} [icon_right_type='google_material_rounded']
27
+ * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'|'lucide_icon'} [icon_right_type='google_material_rounded']
28
28
  * @property {Function} [icon_right_action]
29
29
  * @property {number} [duration=5000]
30
30
  * @property {boolean} [close_on_click=false]
31
31
  * @property {Function} [onclick]
32
32
  */
33
33
 
34
- let debugMode = false;
35
-
36
- const script = document.createElement('script');
37
- script.src = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js';
38
- document.head.appendChild(script);
34
+ /**
35
+ * @typedef {Object} ImportScript
36
+ * @property {Array<'highlightjs'|'material_symbols_rounded'|'material_symbols_outlined'|'lucide'>} names
37
+ */
39
38
 
40
- const link = document.createElement('link');
41
- link.rel = 'stylesheet';
42
- link.href = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css';
43
- document.head.appendChild(link);
39
+ let debugMode = false;
44
40
 
45
41
  const jspt = {
42
+ /**
43
+ * @param {ImportScript} options
44
+ * @returns {void}
45
+ */
46
+ importScript: function(options) {
47
+ const { names } = options;
48
+ names.forEach(name => {
49
+ switch (name) {
50
+ case 'highlightjs':
51
+ const hljs = document.createElement('script');
52
+ hljs.src = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js';
53
+ document.head.appendChild(hljs);
54
+
55
+ const link = document.createElement('link');
56
+ link.rel = 'stylesheet';
57
+ link.href = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css';
58
+ document.head.appendChild(link);
59
+ break;
60
+ case 'material_symbols_rounded':
61
+ const msr = document.createElement('link');
62
+ msr.rel = 'stylesheet';
63
+ msr.href = 'https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200';
64
+ document.head.appendChild(msr);
65
+ break;
66
+ case 'material_symbols_outlined':
67
+ const mso = document.createElement('link');
68
+ mso.rel = 'stylesheet';
69
+ mso.href = 'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200';
70
+ document.head.appendChild(mso);
71
+ break;
72
+ case 'lucide':
73
+ const lucide = document.createElement('script');
74
+ lucide.src = 'https://unpkg.com/lucide@latest';
75
+ document.head.appendChild(lucide);
76
+ break;
77
+ }
78
+ });
79
+ },
80
+
46
81
  /**
47
82
  * @param {ClosePopupOptions} options
48
83
  * @returns {void}
@@ -366,6 +401,9 @@ const jspt = {
366
401
  case 'emoji':
367
402
  iconLeftElement.innerText = icon_left;
368
403
  break;
404
+ case 'lucide_icon':
405
+ iconLeftElement.dataset.lucide = icon_left;
406
+ break;
369
407
  }
370
408
 
371
409
  toast.appendChild(iconLeftElement);
@@ -414,6 +452,9 @@ const jspt = {
414
452
  case 'emoji':
415
453
  iconRightElement.innerText = icon_right;
416
454
  break;
455
+ case 'lucide_icon':
456
+ iconRightElement.dataset.lucide = icon_right;
457
+ break;
417
458
  }
418
459
 
419
460
  toast.appendChild(iconRightElement);
@@ -581,6 +622,7 @@ const jspt = {
581
622
 
582
623
  const mo = new MutationObserver(updateToasts);
583
624
  mo.observe(container, { childList: true });
625
+ if (typeof lucide !== 'undefined') lucide.createIcons();
584
626
  }
585
627
  };
586
628
 
@@ -1,3 +1,5 @@
1
+ import { createIcons, icons } from "https://esm.sh/lucide@0.564.0";
2
+
1
3
  /**
2
4
  * @typedef {Object} PopupOptions
3
5
  * @property {'default'} [style='default']
@@ -21,10 +23,10 @@
21
23
  * @property {string} message
22
24
  * @property {string} [custom_id]
23
25
  * @property {string} [icon_left]
24
- * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'} [icon_left_type='google_material_rounded']
26
+ * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'|'lucide_icon'} [icon_left_type='google_material_rounded']
25
27
  * @property {Function} [icon_left_action]
26
28
  * @property {string} [icon_right]
27
- * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'} [icon_right_type='google_material_rounded']
29
+ * @property {'google_material_rounded'|'google_material_outlined'|'svg'|'image'|'text'|'emoji'|'lucide_icon'} [icon_right_type='google_material_rounded']
28
30
  * @property {Function} [icon_right_action]
29
31
  * @property {number} [duration=5000]
30
32
  * @property {boolean} [close_on_click=false]
@@ -388,6 +390,9 @@ export function makeToast(options) {
388
390
  case 'emoji':
389
391
  iconLeftElement.innerText = icon_left;
390
392
  break;
393
+ case 'lucide_icon':
394
+ iconLeftElement.dataset.lucide = icon_left;
395
+ break;
391
396
  }
392
397
 
393
398
  toast.appendChild(iconLeftElement);
@@ -436,6 +441,9 @@ export function makeToast(options) {
436
441
  case 'emoji':
437
442
  iconRightElement.innerText = icon_right;
438
443
  break;
444
+ case 'lucide_icon':
445
+ iconRightElement.dataset.lucide = icon_right;
446
+ break;
439
447
  }
440
448
 
441
449
  toast.appendChild(iconRightElement);
@@ -603,6 +611,7 @@ export function makeToast(options) {
603
611
 
604
612
  const mo = new MutationObserver(updateToasts);
605
613
  mo.observe(container, { childList: true });
614
+ createIcons({icons});
606
615
  }
607
616
 
608
617
  export default {