artifactuse 0.2.3 → 0.2.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 +5 -1
- package/dist/core/index.d.ts +1 -14
- package/dist/{index-B4BEvWtI.js → index-W575iBkm.js} +1106 -1106
- package/dist/index.js +1 -1
- package/dist/react/ArtifactusePanel.d.ts +2 -1
- package/dist/react/index.js +816 -802
- package/dist/svelte/index.d.ts +6 -84
- package/dist/svelte/index.js +1751 -1730
- package/dist/vue/index.d.ts +4 -56
- package/dist/vue/index.js +692 -666
- package/dist/vue2/composables.d.ts +4 -56
- package/dist/vue2/index.js +250 -137
- package/package.json +1 -1
|
@@ -83,20 +83,7 @@ export function provideArtifactuse(config?: {
|
|
|
83
83
|
};
|
|
84
84
|
initializeContent: (container?: Document) => Promise<void>;
|
|
85
85
|
openArtifact: (artifact: any) => void;
|
|
86
|
-
openFile: (filename: any, code: any, options?: {}) =>
|
|
87
|
-
id: string;
|
|
88
|
-
messageId: string;
|
|
89
|
-
type: string;
|
|
90
|
-
language: string;
|
|
91
|
-
title: any;
|
|
92
|
-
code: string;
|
|
93
|
-
isInline: boolean;
|
|
94
|
-
isPreviewable: boolean;
|
|
95
|
-
isPanelArtifact: boolean;
|
|
96
|
-
size: number;
|
|
97
|
-
lineCount: number;
|
|
98
|
-
createdAt: string;
|
|
99
|
-
};
|
|
86
|
+
openFile: (filename: any, code: any, options?: {}) => any;
|
|
100
87
|
openCode: (code: any, language: any, options?: {}) => {
|
|
101
88
|
id: string;
|
|
102
89
|
messageId: string;
|
|
@@ -207,20 +194,7 @@ export function provideArtifactuse(config?: {
|
|
|
207
194
|
};
|
|
208
195
|
initializeContent: (container?: Document) => Promise<void>;
|
|
209
196
|
openArtifact: (artifact: any) => void;
|
|
210
|
-
openFile: (filename: any, code: any, options?: {}) =>
|
|
211
|
-
id: string;
|
|
212
|
-
messageId: string;
|
|
213
|
-
type: string;
|
|
214
|
-
language: string;
|
|
215
|
-
title: any;
|
|
216
|
-
code: string;
|
|
217
|
-
isInline: boolean;
|
|
218
|
-
isPreviewable: boolean;
|
|
219
|
-
isPanelArtifact: boolean;
|
|
220
|
-
size: number;
|
|
221
|
-
lineCount: number;
|
|
222
|
-
createdAt: string;
|
|
223
|
-
};
|
|
197
|
+
openFile: (filename: any, code: any, options?: {}) => any;
|
|
224
198
|
openCode: (code: any, language: any, options?: {}) => {
|
|
225
199
|
id: string;
|
|
226
200
|
messageId: string;
|
|
@@ -317,20 +291,7 @@ export function createArtifactuseComposable(config?: {}): {
|
|
|
317
291
|
};
|
|
318
292
|
initializeContent: (container?: Document) => Promise<void>;
|
|
319
293
|
openArtifact: (artifact: any) => void;
|
|
320
|
-
openFile: (filename: any, code: any, options?: {}) =>
|
|
321
|
-
id: string;
|
|
322
|
-
messageId: string;
|
|
323
|
-
type: string;
|
|
324
|
-
language: string;
|
|
325
|
-
title: any;
|
|
326
|
-
code: string;
|
|
327
|
-
isInline: boolean;
|
|
328
|
-
isPreviewable: boolean;
|
|
329
|
-
isPanelArtifact: boolean;
|
|
330
|
-
size: number;
|
|
331
|
-
lineCount: number;
|
|
332
|
-
createdAt: string;
|
|
333
|
-
};
|
|
294
|
+
openFile: (filename: any, code: any, options?: {}) => any;
|
|
334
295
|
openCode: (code: any, language: any, options?: {}) => {
|
|
335
296
|
id: string;
|
|
336
297
|
messageId: string;
|
|
@@ -441,20 +402,7 @@ export function createArtifactuseComposable(config?: {}): {
|
|
|
441
402
|
};
|
|
442
403
|
initializeContent: (container?: Document) => Promise<void>;
|
|
443
404
|
openArtifact: (artifact: any) => void;
|
|
444
|
-
openFile: (filename: any, code: any, options?: {}) =>
|
|
445
|
-
id: string;
|
|
446
|
-
messageId: string;
|
|
447
|
-
type: string;
|
|
448
|
-
language: string;
|
|
449
|
-
title: any;
|
|
450
|
-
code: string;
|
|
451
|
-
isInline: boolean;
|
|
452
|
-
isPreviewable: boolean;
|
|
453
|
-
isPanelArtifact: boolean;
|
|
454
|
-
size: number;
|
|
455
|
-
lineCount: number;
|
|
456
|
-
createdAt: string;
|
|
457
|
-
};
|
|
405
|
+
openFile: (filename: any, code: any, options?: {}) => any;
|
|
458
406
|
openCode: (code: any, language: any, options?: {}) => {
|
|
459
407
|
id: string;
|
|
460
408
|
messageId: string;
|
package/dist/vue2/index.js
CHANGED
|
@@ -6,9 +6,160 @@ import require$$2 from 'events';
|
|
|
6
6
|
import require$$0$1 from 'buffer';
|
|
7
7
|
import require$$1 from 'util';
|
|
8
8
|
|
|
9
|
+
// artifactuse/core/highlight.js
|
|
10
|
+
// Optional Prism.js integration for syntax highlighting
|
|
11
|
+
// Users must provide Prism.js themselves
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Check if Prism is available
|
|
15
|
+
*/
|
|
16
|
+
function isPrismAvailable() {
|
|
17
|
+
return typeof window !== 'undefined' && window.Prism;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Highlight all code blocks in a container
|
|
22
|
+
* @param {HTMLElement|string} container - Container element or selector
|
|
23
|
+
*/
|
|
24
|
+
function highlightAll(container) {
|
|
25
|
+
if (!isPrismAvailable()) {
|
|
26
|
+
console.warn('Artifactuse: Prism.js not found. Install and include Prism.js for syntax highlighting.');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const element = typeof container === 'string'
|
|
31
|
+
? document.querySelector(container)
|
|
32
|
+
: container;
|
|
33
|
+
|
|
34
|
+
if (!element) return;
|
|
35
|
+
|
|
36
|
+
// Find all code blocks
|
|
37
|
+
const codeBlocks = element.querySelectorAll('pre code');
|
|
38
|
+
|
|
39
|
+
codeBlocks.forEach(block => {
|
|
40
|
+
// Skip if already highlighted
|
|
41
|
+
if (block.classList.contains('prism-highlighted')) return;
|
|
42
|
+
|
|
43
|
+
// Detect language from class
|
|
44
|
+
const language = detectLanguage(block);
|
|
45
|
+
|
|
46
|
+
if (language) {
|
|
47
|
+
// Add language class if not present
|
|
48
|
+
if (!block.className.includes(`language-${language}`)) {
|
|
49
|
+
block.classList.add(`language-${language}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Highlight
|
|
53
|
+
window.Prism.highlightElement(block);
|
|
54
|
+
block.classList.add('prism-highlighted');
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Highlight code string and return HTML
|
|
61
|
+
* @param {string} code - Code to highlight
|
|
62
|
+
* @param {string} language - Language identifier
|
|
63
|
+
* @returns {string} - Highlighted HTML
|
|
64
|
+
*/
|
|
65
|
+
function highlightCode(code, language) {
|
|
66
|
+
if (!isPrismAvailable()) return escapeHtml$4(code);
|
|
67
|
+
|
|
68
|
+
const grammar = window.Prism.languages[language];
|
|
69
|
+
|
|
70
|
+
if (!grammar) {
|
|
71
|
+
return escapeHtml$4(code);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return window.Prism.highlight(code, grammar, language);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Detect language from element classes
|
|
79
|
+
* @param {HTMLElement} element - Code element
|
|
80
|
+
* @returns {string|null} - Detected language or null
|
|
81
|
+
*/
|
|
82
|
+
function detectLanguage(element) {
|
|
83
|
+
// Check element classes
|
|
84
|
+
const classes = element.className.split(/\s+/);
|
|
85
|
+
|
|
86
|
+
for (const cls of classes) {
|
|
87
|
+
// Match language-xxx or lang-xxx
|
|
88
|
+
const match = cls.match(/^(?:language-|lang-)(.+)$/);
|
|
89
|
+
if (match) {
|
|
90
|
+
return normalizeLanguage(match[1]);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Check parent <pre> classes
|
|
95
|
+
const pre = element.closest('pre');
|
|
96
|
+
if (pre) {
|
|
97
|
+
const preClasses = pre.className.split(/\s+/);
|
|
98
|
+
for (const cls of preClasses) {
|
|
99
|
+
const match = cls.match(/^(?:language-|lang-)(.+)$/);
|
|
100
|
+
if (match) {
|
|
101
|
+
return normalizeLanguage(match[1]);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Check data-language attribute
|
|
107
|
+
const dataLang = element.dataset.language || pre?.dataset.language;
|
|
108
|
+
if (dataLang) {
|
|
109
|
+
return normalizeLanguage(dataLang);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Normalize language identifier to Prism-compatible name
|
|
117
|
+
*/
|
|
118
|
+
function normalizeLanguage(lang) {
|
|
119
|
+
const aliases = {
|
|
120
|
+
'js': 'javascript',
|
|
121
|
+
'ts': 'typescript',
|
|
122
|
+
'py': 'python',
|
|
123
|
+
'rb': 'ruby',
|
|
124
|
+
'sh': 'bash',
|
|
125
|
+
'shell': 'bash',
|
|
126
|
+
'zsh': 'bash',
|
|
127
|
+
'yml': 'yaml',
|
|
128
|
+
'md': 'markdown',
|
|
129
|
+
'html': 'markup',
|
|
130
|
+
'xml': 'markup',
|
|
131
|
+
'svg': 'markup',
|
|
132
|
+
'vue': 'markup',
|
|
133
|
+
'jsx': 'jsx',
|
|
134
|
+
'tsx': 'tsx',
|
|
135
|
+
'c++': 'cpp',
|
|
136
|
+
'c#': 'csharp',
|
|
137
|
+
'cs': 'csharp',
|
|
138
|
+
'f#': 'fsharp',
|
|
139
|
+
'objective-c': 'objectivec',
|
|
140
|
+
'objc': 'objectivec',
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const normalized = lang.toLowerCase();
|
|
144
|
+
return aliases[normalized] || normalized;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Escape HTML special characters
|
|
149
|
+
*/
|
|
150
|
+
function escapeHtml$4(str) {
|
|
151
|
+
return str
|
|
152
|
+
.replace(/&/g, '&')
|
|
153
|
+
.replace(/</g, '<')
|
|
154
|
+
.replace(/>/g, '>')
|
|
155
|
+
.replace(/"/g, '"')
|
|
156
|
+
.replace(/'/g, ''');
|
|
157
|
+
}
|
|
158
|
+
|
|
9
159
|
// artifactuse/core/detector.js
|
|
10
160
|
// Artifact detection and extraction from AI responses
|
|
11
161
|
|
|
162
|
+
|
|
12
163
|
/**
|
|
13
164
|
* Artifact type definitions
|
|
14
165
|
*/
|
|
@@ -447,18 +598,6 @@ function decodeHtml(encoded) {
|
|
|
447
598
|
.replace(/ /g, ' ');
|
|
448
599
|
}
|
|
449
600
|
|
|
450
|
-
/**
|
|
451
|
-
* Encode HTML for safe embedding
|
|
452
|
-
*/
|
|
453
|
-
function encodeHtml(code) {
|
|
454
|
-
return code
|
|
455
|
-
.replace(/&/g, '&')
|
|
456
|
-
.replace(/"/g, '"')
|
|
457
|
-
.replace(/'/g, ''')
|
|
458
|
-
.replace(/</g, '<')
|
|
459
|
-
.replace(/>/g, '>');
|
|
460
|
-
}
|
|
461
|
-
|
|
462
601
|
/**
|
|
463
602
|
* Encode JSON for safe embedding in HTML attributes using Base64
|
|
464
603
|
*/
|
|
@@ -624,16 +763,18 @@ function createInlinePreview(artifact, code, langLower, inlinePreview) {
|
|
|
624
763
|
// Separate markers (+/-/space) from code content
|
|
625
764
|
const markers = truncDiffLines.map(l => l[0] || ' ');
|
|
626
765
|
const codeLines = truncDiffLines.map(l => l.slice(1));
|
|
627
|
-
const encoded = encodeHtml(codeLines.join('\n'));
|
|
628
|
-
const isTruncated = allDiffLines.length > maxLines;
|
|
629
766
|
const actualLang = diffData.language || 'plaintext';
|
|
767
|
+
const normalizedActualLang = normalizeLanguage(actualLang);
|
|
768
|
+
const encoded = highlightCode(codeLines.join('\n'), normalizedActualLang);
|
|
769
|
+
const isPreHighlighted = isPrismAvailable() && window.Prism.languages[normalizedActualLang];
|
|
770
|
+
const isTruncated = allDiffLines.length > maxLines;
|
|
630
771
|
const nonClickable = isNonClickable(allDiffLines.length, isTruncated);
|
|
631
772
|
const staticClass = nonClickable ? ' artifactuse-inline-preview--static' : '';
|
|
632
773
|
const staticAttr = nonClickable ? ' data-non-clickable="true"' : '';
|
|
633
774
|
const actionText = getActionLabel('smartdiff', allDiffLines.length);
|
|
634
775
|
|
|
635
776
|
return `<div class="artifactuse-inline-preview${isTruncated ? ' artifactuse-inline-preview--truncated' : ''}${staticClass}" data-artifact-id="${artifact.id}" data-smartdiff="true" data-smartdiff-markers="${markers.join(',')}"${staticAttr}>`
|
|
636
|
-
+ `<pre class="artifactuse-inline-preview__pre"><code class="language-${actualLang}">${encoded}</code></pre>`
|
|
777
|
+
+ `<pre class="artifactuse-inline-preview__pre${isPreHighlighted ? ' language-' + actualLang : ''}"><code class="language-${actualLang}${isPreHighlighted ? ' prism-highlighted' : ''}">${encoded}</code></pre>`
|
|
637
778
|
+ (isTruncated ? `<div class="artifactuse-inline-preview__fade"><span class="artifactuse-inline-preview__action">${actionText}</span></div>` : '')
|
|
638
779
|
+ `</div>`;
|
|
639
780
|
} catch {
|
|
@@ -647,7 +788,9 @@ function createInlinePreview(artifact, code, langLower, inlinePreview) {
|
|
|
647
788
|
|
|
648
789
|
const lines = previewCode.split('\n');
|
|
649
790
|
const truncated = lines.slice(0, maxLines).join('\n');
|
|
650
|
-
const
|
|
791
|
+
const normalizedLang = normalizeLanguage(previewLang);
|
|
792
|
+
const encoded = highlightCode(truncated, normalizedLang);
|
|
793
|
+
const isPreHighlighted = isPrismAvailable() && window.Prism.languages[normalizedLang];
|
|
651
794
|
const isTruncated = lines.length > maxLines;
|
|
652
795
|
const nonClickable = isNonClickable(lines.length, isTruncated);
|
|
653
796
|
const staticClass = nonClickable ? ' artifactuse-inline-preview--static' : '';
|
|
@@ -655,7 +798,7 @@ function createInlinePreview(artifact, code, langLower, inlinePreview) {
|
|
|
655
798
|
const actionText = getActionLabel(langLower, lines.length);
|
|
656
799
|
|
|
657
800
|
return `<div class="artifactuse-inline-preview${isTruncated ? ' artifactuse-inline-preview--truncated' : ''}${staticClass}" data-artifact-id="${artifact.id}"${staticAttr}>`
|
|
658
|
-
+ `<pre class="artifactuse-inline-preview__pre"><code class="language-${previewLang}">${encoded}</code></pre>`
|
|
801
|
+
+ `<pre class="artifactuse-inline-preview__pre${isPreHighlighted ? ' language-' + previewLang : ''}"><code class="language-${previewLang}${isPreHighlighted ? ' prism-highlighted' : ''}">${encoded}</code></pre>`
|
|
659
802
|
+ (isTruncated ? `<div class="artifactuse-inline-preview__fade"><span class="artifactuse-inline-preview__action">${actionText}</span></div>` : '')
|
|
660
803
|
+ `</div>`;
|
|
661
804
|
}
|
|
@@ -6557,126 +6700,6 @@ function loadKaTeX() {
|
|
|
6557
6700
|
return katexLoadingPromise;
|
|
6558
6701
|
}
|
|
6559
6702
|
|
|
6560
|
-
// artifactuse/core/highlight.js
|
|
6561
|
-
// Optional Prism.js integration for syntax highlighting
|
|
6562
|
-
// Users must provide Prism.js themselves
|
|
6563
|
-
|
|
6564
|
-
/**
|
|
6565
|
-
* Check if Prism is available
|
|
6566
|
-
*/
|
|
6567
|
-
function isPrismAvailable() {
|
|
6568
|
-
return typeof window !== 'undefined' && window.Prism;
|
|
6569
|
-
}
|
|
6570
|
-
|
|
6571
|
-
/**
|
|
6572
|
-
* Highlight all code blocks in a container
|
|
6573
|
-
* @param {HTMLElement|string} container - Container element or selector
|
|
6574
|
-
*/
|
|
6575
|
-
function highlightAll(container) {
|
|
6576
|
-
if (!isPrismAvailable()) {
|
|
6577
|
-
console.warn('Artifactuse: Prism.js not found. Install and include Prism.js for syntax highlighting.');
|
|
6578
|
-
return;
|
|
6579
|
-
}
|
|
6580
|
-
|
|
6581
|
-
const element = typeof container === 'string'
|
|
6582
|
-
? document.querySelector(container)
|
|
6583
|
-
: container;
|
|
6584
|
-
|
|
6585
|
-
if (!element) return;
|
|
6586
|
-
|
|
6587
|
-
// Find all code blocks
|
|
6588
|
-
const codeBlocks = element.querySelectorAll('pre code');
|
|
6589
|
-
|
|
6590
|
-
codeBlocks.forEach(block => {
|
|
6591
|
-
// Skip if already highlighted
|
|
6592
|
-
if (block.classList.contains('prism-highlighted')) return;
|
|
6593
|
-
|
|
6594
|
-
// Detect language from class
|
|
6595
|
-
const language = detectLanguage(block);
|
|
6596
|
-
|
|
6597
|
-
if (language) {
|
|
6598
|
-
// Add language class if not present
|
|
6599
|
-
if (!block.className.includes(`language-${language}`)) {
|
|
6600
|
-
block.classList.add(`language-${language}`);
|
|
6601
|
-
}
|
|
6602
|
-
|
|
6603
|
-
// Highlight
|
|
6604
|
-
window.Prism.highlightElement(block);
|
|
6605
|
-
block.classList.add('prism-highlighted');
|
|
6606
|
-
}
|
|
6607
|
-
});
|
|
6608
|
-
}
|
|
6609
|
-
|
|
6610
|
-
/**
|
|
6611
|
-
* Detect language from element classes
|
|
6612
|
-
* @param {HTMLElement} element - Code element
|
|
6613
|
-
* @returns {string|null} - Detected language or null
|
|
6614
|
-
*/
|
|
6615
|
-
function detectLanguage(element) {
|
|
6616
|
-
// Check element classes
|
|
6617
|
-
const classes = element.className.split(/\s+/);
|
|
6618
|
-
|
|
6619
|
-
for (const cls of classes) {
|
|
6620
|
-
// Match language-xxx or lang-xxx
|
|
6621
|
-
const match = cls.match(/^(?:language-|lang-)(.+)$/);
|
|
6622
|
-
if (match) {
|
|
6623
|
-
return normalizeLanguage(match[1]);
|
|
6624
|
-
}
|
|
6625
|
-
}
|
|
6626
|
-
|
|
6627
|
-
// Check parent <pre> classes
|
|
6628
|
-
const pre = element.closest('pre');
|
|
6629
|
-
if (pre) {
|
|
6630
|
-
const preClasses = pre.className.split(/\s+/);
|
|
6631
|
-
for (const cls of preClasses) {
|
|
6632
|
-
const match = cls.match(/^(?:language-|lang-)(.+)$/);
|
|
6633
|
-
if (match) {
|
|
6634
|
-
return normalizeLanguage(match[1]);
|
|
6635
|
-
}
|
|
6636
|
-
}
|
|
6637
|
-
}
|
|
6638
|
-
|
|
6639
|
-
// Check data-language attribute
|
|
6640
|
-
const dataLang = element.dataset.language || pre?.dataset.language;
|
|
6641
|
-
if (dataLang) {
|
|
6642
|
-
return normalizeLanguage(dataLang);
|
|
6643
|
-
}
|
|
6644
|
-
|
|
6645
|
-
return null;
|
|
6646
|
-
}
|
|
6647
|
-
|
|
6648
|
-
/**
|
|
6649
|
-
* Normalize language identifier to Prism-compatible name
|
|
6650
|
-
*/
|
|
6651
|
-
function normalizeLanguage(lang) {
|
|
6652
|
-
const aliases = {
|
|
6653
|
-
'js': 'javascript',
|
|
6654
|
-
'ts': 'typescript',
|
|
6655
|
-
'py': 'python',
|
|
6656
|
-
'rb': 'ruby',
|
|
6657
|
-
'sh': 'bash',
|
|
6658
|
-
'shell': 'bash',
|
|
6659
|
-
'zsh': 'bash',
|
|
6660
|
-
'yml': 'yaml',
|
|
6661
|
-
'md': 'markdown',
|
|
6662
|
-
'html': 'markup',
|
|
6663
|
-
'xml': 'markup',
|
|
6664
|
-
'svg': 'markup',
|
|
6665
|
-
'vue': 'markup',
|
|
6666
|
-
'jsx': 'jsx',
|
|
6667
|
-
'tsx': 'tsx',
|
|
6668
|
-
'c++': 'cpp',
|
|
6669
|
-
'c#': 'csharp',
|
|
6670
|
-
'cs': 'csharp',
|
|
6671
|
-
'f#': 'fsharp',
|
|
6672
|
-
'objective-c': 'objectivec',
|
|
6673
|
-
'objc': 'objectivec',
|
|
6674
|
-
};
|
|
6675
|
-
|
|
6676
|
-
const normalized = lang.toLowerCase();
|
|
6677
|
-
return aliases[normalized] || normalized;
|
|
6678
|
-
}
|
|
6679
|
-
|
|
6680
6703
|
// artifactuse/core/index.js
|
|
6681
6704
|
// Main entry point for Artifactuse SDK
|
|
6682
6705
|
|
|
@@ -6839,6 +6862,10 @@ const DEFAULT_CONFIG = {
|
|
|
6839
6862
|
// Can be overridden per-component via props
|
|
6840
6863
|
splitPosition: 50,
|
|
6841
6864
|
|
|
6865
|
+
// Show "Open in new tab" button in panel header to open preview URL externally
|
|
6866
|
+
// Can be overridden per-artifact via openFile/openCode options or per-component via props
|
|
6867
|
+
externalPreview: false,
|
|
6868
|
+
|
|
6842
6869
|
// Enable multi-tab mode (open multiple artifacts as tabs)
|
|
6843
6870
|
multiTab: false,
|
|
6844
6871
|
|
|
@@ -7369,6 +7396,17 @@ function createArtifactuse(userConfig = {}) {
|
|
|
7369
7396
|
const ext = filename.split('.').pop();
|
|
7370
7397
|
const language = options.language || getLanguageFromExtension(ext) || ext;
|
|
7371
7398
|
const title = options.title || filename;
|
|
7399
|
+
|
|
7400
|
+
// Deduplicate: if an artifact with the same title already exists, update + focus it
|
|
7401
|
+
const existing = state.getState().artifacts.find(a => a.title === title && !a.isInline);
|
|
7402
|
+
if (existing) {
|
|
7403
|
+
updateFile(existing.id, code, { ...options, title });
|
|
7404
|
+
openArtifact(existing);
|
|
7405
|
+
if (options.viewMode) state.setViewMode(options.viewMode);
|
|
7406
|
+
else if (options.tabs) state.setViewMode(options.tabs[0]);
|
|
7407
|
+
return state.getArtifact(existing.id);
|
|
7408
|
+
}
|
|
7409
|
+
|
|
7372
7410
|
return openCode(code, language, { ...options, title });
|
|
7373
7411
|
}
|
|
7374
7412
|
|
|
@@ -7384,6 +7422,7 @@ function createArtifactuse(userConfig = {}) {
|
|
|
7384
7422
|
artifact.editorLanguage = language;
|
|
7385
7423
|
if (options.tabs) artifact.tabs = options.tabs;
|
|
7386
7424
|
if (options.panelUrl) artifact.panelUrl = options.panelUrl;
|
|
7425
|
+
if (options.externalPreview !== undefined) artifact.externalPreview = options.externalPreview;
|
|
7387
7426
|
state.addArtifact(artifact);
|
|
7388
7427
|
openArtifact(artifact);
|
|
7389
7428
|
if (options.viewMode) state.setViewMode(options.viewMode);
|
|
@@ -7403,6 +7442,7 @@ function createArtifactuse(userConfig = {}) {
|
|
|
7403
7442
|
if (options.title !== undefined) updates.title = options.title;
|
|
7404
7443
|
if (options.tabs !== undefined) updates.tabs = options.tabs;
|
|
7405
7444
|
if (options.panelUrl !== undefined) updates.panelUrl = options.panelUrl;
|
|
7445
|
+
if (options.externalPreview !== undefined) updates.externalPreview = options.externalPreview;
|
|
7406
7446
|
|
|
7407
7447
|
state.addArtifact(updates);
|
|
7408
7448
|
emit('artifact:updated', { artifactId: id, artifact: state.getArtifact(id) });
|
|
@@ -27605,6 +27645,18 @@ var JSZip = /*@__PURE__*/getDefaultExportFromCjs(libExports);
|
|
|
27605
27645
|
//
|
|
27606
27646
|
//
|
|
27607
27647
|
//
|
|
27648
|
+
//
|
|
27649
|
+
//
|
|
27650
|
+
//
|
|
27651
|
+
//
|
|
27652
|
+
//
|
|
27653
|
+
//
|
|
27654
|
+
//
|
|
27655
|
+
//
|
|
27656
|
+
//
|
|
27657
|
+
//
|
|
27658
|
+
//
|
|
27659
|
+
//
|
|
27608
27660
|
|
|
27609
27661
|
|
|
27610
27662
|
var script$1 = defineComponent({
|
|
@@ -27624,6 +27676,10 @@ var script$1 = defineComponent({
|
|
|
27624
27676
|
type: Number,
|
|
27625
27677
|
default: undefined,
|
|
27626
27678
|
},
|
|
27679
|
+
externalPreview: {
|
|
27680
|
+
type: Boolean,
|
|
27681
|
+
default: undefined,
|
|
27682
|
+
},
|
|
27627
27683
|
},
|
|
27628
27684
|
|
|
27629
27685
|
setup(props, { emit }) {
|
|
@@ -27729,6 +27785,13 @@ var script$1 = defineComponent({
|
|
|
27729
27785
|
return instance.config?.branding !== false;
|
|
27730
27786
|
});
|
|
27731
27787
|
|
|
27788
|
+
const showExternalPreview = computed(() => {
|
|
27789
|
+
if (!panelUrl.value) return false;
|
|
27790
|
+
if (activeArtifact.value?.externalPreview !== undefined) return activeArtifact.value.externalPreview;
|
|
27791
|
+
if (props.externalPreview !== undefined) return props.externalPreview;
|
|
27792
|
+
return instance.config?.externalPreview ?? false;
|
|
27793
|
+
});
|
|
27794
|
+
|
|
27732
27795
|
// Multi-tab computed
|
|
27733
27796
|
const isMultiTab = computed(() => instance.config?.multiTab === true);
|
|
27734
27797
|
|
|
@@ -27878,6 +27941,10 @@ var script$1 = defineComponent({
|
|
|
27878
27941
|
});
|
|
27879
27942
|
}
|
|
27880
27943
|
|
|
27944
|
+
function handleExternalPreview() {
|
|
27945
|
+
if (panelUrl.value) window.open(panelUrl.value, '_blank', 'noopener,noreferrer');
|
|
27946
|
+
}
|
|
27947
|
+
|
|
27881
27948
|
function handleIframeLoad() {
|
|
27882
27949
|
clearTimeout(iframeLoadTimer);
|
|
27883
27950
|
iframeLoading.value = false;
|
|
@@ -28421,6 +28488,7 @@ var script$1 = defineComponent({
|
|
|
28421
28488
|
nonInlineArtifacts,
|
|
28422
28489
|
currentNonInlineIndex,
|
|
28423
28490
|
showBranding,
|
|
28491
|
+
showExternalPreview,
|
|
28424
28492
|
effectivePanelWidth,
|
|
28425
28493
|
panelClasses,
|
|
28426
28494
|
forceEmptyView,
|
|
@@ -28445,6 +28513,7 @@ var script$1 = defineComponent({
|
|
|
28445
28513
|
startPanelResize,
|
|
28446
28514
|
startSplitResize,
|
|
28447
28515
|
handleEditorSave,
|
|
28516
|
+
handleExternalPreview,
|
|
28448
28517
|
|
|
28449
28518
|
// Multi-tab methods
|
|
28450
28519
|
selectTab,
|
|
@@ -29480,6 +29549,50 @@ var __vue_render__$1 = function () {
|
|
|
29480
29549
|
)
|
|
29481
29550
|
: _vm._e(),
|
|
29482
29551
|
_vm._v(" "),
|
|
29552
|
+
_vm.showExternalPreview
|
|
29553
|
+
? _c(
|
|
29554
|
+
"button",
|
|
29555
|
+
{
|
|
29556
|
+
staticClass: "artifactuse-panel__action",
|
|
29557
|
+
attrs: { title: "Open in new tab" },
|
|
29558
|
+
on: { click: _vm.handleExternalPreview },
|
|
29559
|
+
},
|
|
29560
|
+
[
|
|
29561
|
+
_c(
|
|
29562
|
+
"svg",
|
|
29563
|
+
{
|
|
29564
|
+
attrs: {
|
|
29565
|
+
viewBox: "0 0 24 24",
|
|
29566
|
+
fill: "none",
|
|
29567
|
+
stroke: "currentColor",
|
|
29568
|
+
"stroke-width": "2",
|
|
29569
|
+
},
|
|
29570
|
+
},
|
|
29571
|
+
[
|
|
29572
|
+
_c("path", {
|
|
29573
|
+
attrs: {
|
|
29574
|
+
d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",
|
|
29575
|
+
},
|
|
29576
|
+
}),
|
|
29577
|
+
_vm._v(" "),
|
|
29578
|
+
_c("polyline", {
|
|
29579
|
+
attrs: { points: "15 3 21 3 21 9" },
|
|
29580
|
+
}),
|
|
29581
|
+
_vm._v(" "),
|
|
29582
|
+
_c("line", {
|
|
29583
|
+
attrs: {
|
|
29584
|
+
x1: "10",
|
|
29585
|
+
y1: "14",
|
|
29586
|
+
x2: "21",
|
|
29587
|
+
y2: "3",
|
|
29588
|
+
},
|
|
29589
|
+
}),
|
|
29590
|
+
]
|
|
29591
|
+
),
|
|
29592
|
+
]
|
|
29593
|
+
)
|
|
29594
|
+
: _vm._e(),
|
|
29595
|
+
_vm._v(" "),
|
|
29483
29596
|
_c(
|
|
29484
29597
|
"button",
|
|
29485
29598
|
{
|