-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtemp-original.txt
More file actions
192 lines (155 loc) · 5.85 KB
/
temp-original.txt
File metadata and controls
192 lines (155 loc) · 5.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
using System.Reflection;
using System.Text;
namespace SchemaMagic.Tool;
public static class ModularHtmlTemplate
{
private static readonly Dictionary<string, string> _templateCache = [];
public static string Generate(string entitiesJson, string? documentGuid = null, string? customCssPath = null)
{
// Generate a new GUID if none provided
var guid = documentGuid ?? Guid.NewGuid().ToString();
var html = LoadTemplate("template.html");
var css = GetMergedCss(customCssPath);
var javascript = CombineJavaScriptFiles(entitiesJson, guid);
// Replace placeholders
html = html.Replace("<!-- CSS STYLES -->", $"<style>\n{css}\n</style>");
html = html.Replace("<!-- JAVASCRIPT CONTENT -->", javascript);
return html;
}
public static string GenerateForDownload(string entitiesJson, Dictionary<string, object> currentState, string? customCssPath = null)
{
// Generate a new GUID for the downloaded document
var newGuid = Guid.NewGuid().ToString();
var html = LoadTemplate("template.html");
var css = GetMergedCss(customCssPath);
var javascript = CombineJavaScriptFiles(entitiesJson, newGuid, currentState);
// Replace placeholders
html = html.Replace("<!-- CSS STYLES -->", $"<style>\n{css}\n</style>");
html = html.Replace("<!-- JAVASCRIPT CONTENT -->", javascript);
return html;
}
public static string GetDefaultCss()
{
return LoadTemplate("styles.css");
}
private static string GetMergedCss(string? customCssPath)
{
var defaultCss = LoadTemplate("styles.css");
// If no custom CSS provided, return default
if (string.IsNullOrEmpty(customCssPath) || !File.Exists(customCssPath))
{
return defaultCss;
}
try
{
var customCss = File.ReadAllText(customCssPath);
// Create merged CSS with proper comments and organization
var mergedCss = new StringBuilder();
// Add header comment
mergedCss.AppendLine("/* SchemaMagic Generated Styles */");
mergedCss.AppendLine("/* Default styles with custom overrides applied */");
mergedCss.AppendLine();
// Add default styles first
mergedCss.AppendLine("/* ========== DEFAULT STYLES ========== */");
mergedCss.AppendLine(defaultCss);
mergedCss.AppendLine();
// Add custom overrides
mergedCss.AppendLine("/* ========== CUSTOM OVERRIDES ========== */");
mergedCss.AppendLine($"/* Loaded from: {Path.GetFileName(customCssPath)} */");
mergedCss.AppendLine(customCss);
Console.WriteLine($"🎨 CSS merged successfully:");
Console.WriteLine($" Default styles: {defaultCss.Length:N0} characters");
Console.WriteLine($" Custom styles: {customCss.Length:N0} characters");
Console.WriteLine($" Total merged: {mergedCss.Length:N0} characters");
return mergedCss.ToString();
}
catch (Exception ex)
{
Console.WriteLine($"⚠️ Warning: Could not load custom CSS file '{customCssPath}': {ex.Message}");
Console.WriteLine("🔄 Falling back to default styles");
return defaultCss;
}
}
private static string CombineJavaScriptFiles(string entitiesJson, string documentGuid, Dictionary<string, object>? embeddedState = null)
{
var jsFiles = new[]
{
"variables.js",
"event-listeners.js",
"pan-zoom.js",
"settings.js",
"force-directed-layout.js", // Add force-directed layout before schema-generation
"schema-generation.js",
"table-generation.js",
"property-utilities.js",
"table-interaction.js",
"relationships.js",
"controls.js"
};
var combinedJs = string.Join("\n\n", jsFiles.Select(LoadTemplate));
// Replace the entities JSON placeholder
combinedJs = combinedJs.Replace("ENTITIES_JSON_PLACEHOLDER", entitiesJson);
// Replace the document GUID placeholder
combinedJs = combinedJs.Replace("DOCUMENT_GUID_PLACEHOLDER", documentGuid);
// If we have embedded state (for download), inject it
if (embeddedState != null)
{
var stateScript = GenerateEmbeddedStateScript(embeddedState, documentGuid);
combinedJs += "\n\n" + stateScript;
}
return combinedJs;
}
private static string GenerateEmbeddedStateScript(Dictionary<string, object> state, string documentGuid)
{
var script = @"
// Embedded state for downloaded document
// This acts as a proxy for localStorage to preserve user customizations
(function() {
const embeddedState = " + System.Text.Json.JsonSerializer.Serialize(state) + @";
const originalGuid = '" + documentGuid + @"';
// Override localStorage for this document's keys
const originalGetItem = localStorage.getItem.bind(localStorage);
const originalSetItem = localStorage.setItem.bind(localStorage);
localStorage.getItem = function(key) {
// Check if this is one of our document-specific keys
if (key.startsWith(`schemaMagic_${originalGuid}_`)) {
const keyType = key.replace(`schemaMagic_${originalGuid}_`, '');
return embeddedState[keyType] || null;
}
return originalGetItem(key);
};
localStorage.setItem = function(key, value) {
// Allow normal localStorage operation for the new document GUID
originalSetItem(key, value);
};
console.log('📦 Downloaded document with embedded state from original document');
})();";
return script;
}
private static string LoadTemplate(string fileName)
{
if (_templateCache.TryGetValue(fileName, out var cached))
{
return cached;
}
var assembly = Assembly.GetExecutingAssembly();
var resourceName = $"SchemaMagic.Tool.Templates.{fileName}";
using var stream = assembly.GetManifestResourceStream(resourceName);
if (stream == null)
{
// Fallback to file system if embedded resource not found
var filePath = Path.Combine("Templates", fileName);
if (File.Exists(filePath))
{
var content = File.ReadAllText(filePath);
_templateCache[fileName] = content;
return content;
}
throw new FileNotFoundException($"Template file not found: {fileName}");
}
using var reader = new StreamReader(stream);
var template = reader.ReadToEnd();
_templateCache[fileName] = template;
return template;
}
}