Skip to content

Commit cc1ce8f

Browse files
authored
Merge pull request #15 from vanzan01/performance/optimize-script-loading
perf: Optimize script loading and reduce inline code for v1.0.1
2 parents 9e84a40 + 428386b commit cc1ce8f

File tree

4 files changed

+158
-160
lines changed

4 files changed

+158
-160
lines changed

src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"font-src": "'self' https://fonts.gstatic.com",
4747
"img-src": "'self' asset: http://asset.localhost blob: data: file: https://httpbin.org https://via.placeholder.com https://picsum.photos https://images.unsplash.com https://raw.githubusercontent.com",
4848
"style-src": "'unsafe-inline' 'self' https://fonts.googleapis.com https://unpkg.com",
49-
"script-src": "'self' 'unsafe-inline' 'unsafe-eval' https://unpkg.com https://esm.sh https://cdn.jsdelivr.net",
49+
"script-src": "'self' https://unpkg.com https://esm.sh https://cdn.jsdelivr.net",
5050
"worker-src": "'self' blob:",
5151
"object-src": "'none'",
5252
"base-uri": "'self'",

src/docx-generator.js

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// DOCX generation using the docx.js library
2+
window.generateDocxFromMarkdown = async function(markdownText, title) {
3+
console.log('🔄 Generating DOCX using docx.js library...');
4+
5+
try {
6+
// Convert markdown to HTML first
7+
const html = await window.__TAURI__.core.invoke('parse_markdown', { markdownContent: markdownText });
8+
9+
// Parse the HTML to extract content
10+
const parser = new DOMParser();
11+
const doc = parser.parseFromString(html, 'text/html');
12+
13+
// Create paragraphs from the HTML content
14+
const paragraphs = [];
15+
16+
// Add title
17+
paragraphs.push(
18+
new docx.Paragraph({
19+
text: title,
20+
heading: docx.HeadingLevel.TITLE,
21+
spacing: { after: 400 }
22+
})
23+
);
24+
25+
// Process HTML elements
26+
const elements = doc.body.children;
27+
for (let i = 0; i < elements.length; i++) {
28+
const element = elements[i];
29+
30+
if (element.tagName === 'P') {
31+
paragraphs.push(
32+
new docx.Paragraph({
33+
text: element.textContent,
34+
spacing: { after: 200 }
35+
})
36+
);
37+
} else if (element.tagName.match(/^H[1-6]$/)) {
38+
const level = parseInt(element.tagName.substring(1));
39+
paragraphs.push(
40+
new docx.Paragraph({
41+
text: element.textContent,
42+
heading: level <= 3 ? docx.HeadingLevel['HEADING_' + level] : docx.HeadingLevel.HEADING_3,
43+
spacing: { before: 300, after: 200 }
44+
})
45+
);
46+
} else if (element.tagName === 'UL' || element.tagName === 'OL') {
47+
const listItems = element.getElementsByTagName('li');
48+
for (let j = 0; j < listItems.length; j++) {
49+
paragraphs.push(
50+
new docx.Paragraph({
51+
text: listItems[j].textContent,
52+
bullet: element.tagName === 'UL' ? { level: 0 } : undefined,
53+
numbering: element.tagName === 'OL' ? { reference: "default-numbering", level: 0 } : undefined,
54+
spacing: { after: 100 }
55+
})
56+
);
57+
}
58+
} else if (element.tagName === 'BLOCKQUOTE') {
59+
paragraphs.push(
60+
new docx.Paragraph({
61+
text: element.textContent,
62+
style: "Quote",
63+
indent: { left: 720 },
64+
spacing: { after: 200 }
65+
})
66+
);
67+
} else if (element.tagName === 'PRE') {
68+
paragraphs.push(
69+
new docx.Paragraph({
70+
text: element.textContent,
71+
style: "Code",
72+
spacing: { after: 200 }
73+
})
74+
);
75+
}
76+
}
77+
78+
// Create the document
79+
const document = new docx.Document({
80+
sections: [{
81+
properties: {},
82+
children: paragraphs
83+
}]
84+
});
85+
86+
// Generate DOCX file as blob (browser-compatible)
87+
const blob = await docx.Packer.toBlob(document);
88+
console.log('✅ DOCX blob generated successfully, size:', blob.size);
89+
90+
// Convert blob to Uint8Array for Tauri
91+
const arrayBuffer = await blob.arrayBuffer();
92+
return new Uint8Array(arrayBuffer);
93+
94+
} catch (error) {
95+
console.error('❌ Failed to generate DOCX:', error);
96+
throw error;
97+
}
98+
};
99+
100+
// Mark as ready
101+
window.docxReady = true;
102+
console.log('✅ DOCX generator loaded (docx.js)');

src/index.html

Lines changed: 2 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -23,166 +23,9 @@
2323
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/highlight.min.js"
2424
integrity="sha384-F/bZzf7p3Joyp5psL90p/p89AZJsndkSoGwRpXcZhleCWhd8SnRuoYo4d0yirjJp"
2525
crossorigin="anonymous"></script>
26-
<script>
27-
// DOCX generation using the docx.js library
28-
window.generateDocxFromMarkdown = async function(markdownText, title) {
29-
console.log('🔄 Generating DOCX using docx.js library...');
30-
31-
try {
32-
// Convert markdown to HTML first
33-
const html = await window.__TAURI__.core.invoke('parse_markdown', { markdownContent: markdownText });
34-
35-
// Parse the HTML to extract content
36-
const parser = new DOMParser();
37-
const doc = parser.parseFromString(html, 'text/html');
38-
39-
// Create paragraphs from the HTML content
40-
const paragraphs = [];
41-
42-
// Add title
43-
paragraphs.push(
44-
new docx.Paragraph({
45-
text: title,
46-
heading: docx.HeadingLevel.TITLE,
47-
spacing: { after: 400 }
48-
})
49-
);
50-
51-
// Process HTML elements
52-
const elements = doc.body.children;
53-
for (let i = 0; i < elements.length; i++) {
54-
const element = elements[i];
55-
56-
if (element.tagName === 'P') {
57-
paragraphs.push(
58-
new docx.Paragraph({
59-
text: element.textContent,
60-
spacing: { after: 200 }
61-
})
62-
);
63-
} else if (element.tagName.match(/^H[1-6]$/)) {
64-
const level = parseInt(element.tagName.substring(1));
65-
paragraphs.push(
66-
new docx.Paragraph({
67-
text: element.textContent,
68-
heading: level <= 3 ? docx.HeadingLevel['HEADING_' + level] : docx.HeadingLevel.HEADING_3,
69-
spacing: { before: 300, after: 200 }
70-
})
71-
);
72-
} else if (element.tagName === 'UL' || element.tagName === 'OL') {
73-
const listItems = element.getElementsByTagName('li');
74-
for (let j = 0; j < listItems.length; j++) {
75-
paragraphs.push(
76-
new docx.Paragraph({
77-
text: listItems[j].textContent,
78-
bullet: element.tagName === 'UL' ? { level: 0 } : undefined,
79-
numbering: element.tagName === 'OL' ? { reference: "default-numbering", level: 0 } : undefined,
80-
spacing: { after: 100 }
81-
})
82-
);
83-
}
84-
} else if (element.tagName === 'BLOCKQUOTE') {
85-
paragraphs.push(
86-
new docx.Paragraph({
87-
text: element.textContent,
88-
style: "Quote",
89-
indent: { left: 720 },
90-
spacing: { after: 200 }
91-
})
92-
);
93-
} else if (element.tagName === 'PRE') {
94-
paragraphs.push(
95-
new docx.Paragraph({
96-
text: element.textContent,
97-
style: "Code",
98-
spacing: { after: 200 }
99-
})
100-
);
101-
}
102-
}
103-
104-
// Create the document
105-
const document = new docx.Document({
106-
sections: [{
107-
properties: {},
108-
children: paragraphs
109-
}]
110-
});
111-
112-
// Generate DOCX file as blob (browser-compatible)
113-
const blob = await docx.Packer.toBlob(document);
114-
console.log('✅ DOCX blob generated successfully, size:', blob.size);
115-
116-
// Convert blob to Uint8Array for Tauri
117-
const arrayBuffer = await blob.arrayBuffer();
118-
return new Uint8Array(arrayBuffer);
119-
120-
} catch (error) {
121-
console.error('❌ Failed to generate DOCX:', error);
122-
throw error;
123-
}
124-
};
125-
126-
// Mark as ready
127-
window.docxReady = true;
128-
console.log('✅ DOCX generator loaded (docx.js)');
129-
</script>
130-
<script>
131-
// Initialize highlight.js for syntax highlighting
132-
document.addEventListener('DOMContentLoaded', function() {
133-
if (typeof hljs !== 'undefined') {
134-
// Configure highlight.js
135-
hljs.configure({
136-
languages: ['javascript', 'typescript', 'python', 'rust', 'html', 'css', 'sql', 'json', 'bash', 'shell', 'yaml', 'xml', 'markdown', 'c', 'cpp', 'java', 'go', 'php', 'ruby', 'swift', 'kotlin']
137-
});
138-
139-
// Mark as ready
140-
window.highlightJsReady = true;
141-
console.log('✅ Highlight.js initialized successfully');
142-
143-
// Function to highlight all code blocks
144-
window.highlightCodeBlocks = function() {
145-
if (typeof hljs !== 'undefined') {
146-
// Find all code blocks that haven't been highlighted yet
147-
const codeBlocks = document.querySelectorAll('pre code:not(.hljs)');
148-
codeBlocks.forEach(block => {
149-
try {
150-
hljs.highlightElement(block);
151-
} catch (error) {
152-
console.warn('Error highlighting code block:', error);
153-
}
154-
});
155-
}
156-
};
157-
158-
// Function to switch highlight.js theme based on color scheme
159-
window.updateHighlightTheme = function() {
160-
const lightTheme = document.getElementById('highlight-theme-light');
161-
const darkTheme = document.getElementById('highlight-theme-dark');
162-
const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
163-
164-
if (isDarkMode) {
165-
lightTheme.disabled = true;
166-
darkTheme.disabled = false;
167-
} else {
168-
lightTheme.disabled = false;
169-
darkTheme.disabled = true;
170-
}
171-
};
172-
173-
// Initial theme setup
174-
window.updateHighlightTheme();
175-
176-
// Listen for color scheme changes
177-
if (window.matchMedia) {
178-
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', window.updateHighlightTheme);
179-
}
180-
} else {
181-
console.warn('⚠️ Highlight.js not available');
182-
}
183-
});
184-
</script>
18526
<script src="https://unpkg.com/file-saver@2.0.5/dist/FileSaver.min.js"></script>
27+
<script src="/docx-generator.js"></script>
28+
<script src="/syntax-highlighting.js"></script>
18629
<script type="module" src="/main.js" defer></script>
18730
</head>
18831

src/syntax-highlighting.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Initialize highlight.js for syntax highlighting
2+
document.addEventListener('DOMContentLoaded', function() {
3+
if (typeof hljs !== 'undefined') {
4+
// Configure highlight.js
5+
hljs.configure({
6+
languages: ['javascript', 'typescript', 'python', 'rust', 'html', 'css', 'sql', 'json', 'bash', 'shell', 'yaml', 'xml', 'markdown', 'c', 'cpp', 'java', 'go', 'php', 'ruby', 'swift', 'kotlin']
7+
});
8+
9+
// Mark as ready
10+
window.highlightJsReady = true;
11+
console.log('✅ Highlight.js initialized successfully');
12+
13+
// Function to highlight all code blocks
14+
window.highlightCodeBlocks = function() {
15+
if (typeof hljs !== 'undefined') {
16+
// Find all code blocks that haven't been highlighted yet
17+
const codeBlocks = document.querySelectorAll('pre code:not(.hljs)');
18+
codeBlocks.forEach(block => {
19+
try {
20+
hljs.highlightElement(block);
21+
} catch (error) {
22+
console.warn('Error highlighting code block:', error);
23+
}
24+
});
25+
}
26+
};
27+
28+
// Function to switch highlight.js theme based on color scheme
29+
window.updateHighlightTheme = function() {
30+
const lightTheme = document.getElementById('highlight-theme-light');
31+
const darkTheme = document.getElementById('highlight-theme-dark');
32+
const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
33+
34+
if (isDarkMode) {
35+
lightTheme.disabled = true;
36+
darkTheme.disabled = false;
37+
} else {
38+
lightTheme.disabled = false;
39+
darkTheme.disabled = true;
40+
}
41+
};
42+
43+
// Initial theme setup
44+
window.updateHighlightTheme();
45+
46+
// Listen for color scheme changes
47+
if (window.matchMedia) {
48+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', window.updateHighlightTheme);
49+
}
50+
} else {
51+
console.warn('⚠️ Highlight.js not available');
52+
}
53+
});

0 commit comments

Comments
 (0)