aeo.js 0.0.3 → 0.0.4

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/dist/react.js CHANGED
@@ -18,7 +18,7 @@ function getStyles(theme) {
18
18
 
19
19
  .aeo-toggle {
20
20
  position: fixed;
21
- z-index: 10001;
21
+ z-index: 2147483647;
22
22
  font-family: 'JetBrains Mono', monospace;
23
23
  font-size: 14px;
24
24
  animation: aeo-fade-in 0.3s ease;
@@ -92,12 +92,15 @@ function getStyles(theme) {
92
92
  left: 0;
93
93
  right: 0;
94
94
  bottom: 0;
95
+ width: 100vw;
96
+ height: 100vh;
95
97
  background: ${t.background};
96
- z-index: 10000;
98
+ z-index: 2147483646;
97
99
  display: flex;
98
100
  flex-direction: column;
99
101
  animation: aeo-fade-in 0.2s ease;
100
102
  font-family: 'JetBrains Mono', monospace;
103
+ isolation: isolate;
101
104
  }
102
105
 
103
106
  /* Top bar */
@@ -220,6 +223,177 @@ function getStyles(theme) {
220
223
  stroke: currentColor;
221
224
  }
222
225
 
226
+ /* View tabs */
227
+ .aeo-view-tabs {
228
+ display: flex;
229
+ gap: 2px;
230
+ background: rgba(255, 255, 255, 0.05);
231
+ border-radius: 8px;
232
+ padding: 2px;
233
+ border: 1px solid rgba(255, 255, 255, 0.08);
234
+ }
235
+
236
+ .aeo-view-tab {
237
+ padding: 5px 12px;
238
+ background: transparent;
239
+ color: ${t.text};
240
+ border: none;
241
+ border-radius: 6px;
242
+ font-family: inherit;
243
+ font-size: 12px;
244
+ font-weight: 500;
245
+ cursor: pointer;
246
+ transition: all 0.15s ease;
247
+ }
248
+
249
+ .aeo-view-tab:hover {
250
+ background: rgba(255, 255, 255, 0.05);
251
+ }
252
+
253
+ .aeo-view-tab.aeo-view-active {
254
+ background: rgba(255, 255, 255, 0.1);
255
+ color: ${t.accent};
256
+ }
257
+
258
+ /* Metadata bar */
259
+ .aeo-meta-bar {
260
+ display: flex;
261
+ flex-wrap: wrap;
262
+ align-items: center;
263
+ gap: 16px;
264
+ padding: 12px 16px;
265
+ margin-bottom: 24px;
266
+ background: rgba(255, 255, 255, 0.03);
267
+ border: 1px solid rgba(255, 255, 255, 0.06);
268
+ border-radius: 8px;
269
+ font-size: 12px;
270
+ color: ${t.text};
271
+ }
272
+
273
+ .aeo-meta-label {
274
+ color: rgba(160, 160, 168, 0.5);
275
+ margin-right: 4px;
276
+ }
277
+
278
+ .aeo-meta-sep {
279
+ width: 1px;
280
+ height: 14px;
281
+ background: rgba(255, 255, 255, 0.1);
282
+ }
283
+
284
+ /* Rendered markdown view */
285
+ .aeo-rendered {
286
+ color: ${t.text};
287
+ line-height: 1.75;
288
+ font-size: 14px;
289
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
290
+ }
291
+
292
+ .aeo-rendered .aeo-r-h1 {
293
+ font-size: 28px;
294
+ font-weight: 700;
295
+ color: ${t.accent};
296
+ margin: 0 0 16px;
297
+ padding-bottom: 12px;
298
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
299
+ line-height: 1.3;
300
+ }
301
+
302
+ .aeo-rendered .aeo-r-h2 {
303
+ font-size: 22px;
304
+ font-weight: 600;
305
+ color: ${t.accent};
306
+ margin: 32px 0 12px;
307
+ line-height: 1.3;
308
+ }
309
+
310
+ .aeo-rendered .aeo-r-h3 {
311
+ font-size: 18px;
312
+ font-weight: 600;
313
+ color: ${t.accent};
314
+ margin: 24px 0 8px;
315
+ line-height: 1.4;
316
+ }
317
+
318
+ .aeo-rendered .aeo-r-h4,
319
+ .aeo-rendered .aeo-r-h5,
320
+ .aeo-rendered .aeo-r-h6 {
321
+ font-size: 15px;
322
+ font-weight: 600;
323
+ color: ${t.accent};
324
+ margin: 20px 0 8px;
325
+ }
326
+
327
+ .aeo-rendered .aeo-r-p {
328
+ margin: 0 0 12px;
329
+ }
330
+
331
+ .aeo-rendered .aeo-r-list {
332
+ margin: 0 0 16px;
333
+ padding-left: 24px;
334
+ }
335
+
336
+ .aeo-rendered .aeo-r-list li {
337
+ margin: 4px 0;
338
+ }
339
+
340
+ .aeo-rendered .aeo-r-quote {
341
+ margin: 16px 0;
342
+ padding: 12px 20px;
343
+ border-left: 3px solid ${t.badge};
344
+ background: rgba(255, 255, 255, 0.02);
345
+ color: ${t.text};
346
+ font-style: italic;
347
+ }
348
+
349
+ .aeo-rendered .aeo-r-hr {
350
+ border: none;
351
+ border-top: 1px solid rgba(255, 255, 255, 0.08);
352
+ margin: 24px 0;
353
+ }
354
+
355
+ .aeo-rendered .aeo-r-code {
356
+ background: rgba(255, 255, 255, 0.05);
357
+ border: 1px solid rgba(255, 255, 255, 0.08);
358
+ border-radius: 8px;
359
+ padding: 16px;
360
+ margin: 16px 0;
361
+ font-family: 'JetBrains Mono', monospace;
362
+ font-size: 13px;
363
+ overflow-x: auto;
364
+ color: ${t.badge};
365
+ }
366
+
367
+ .aeo-rendered .aeo-r-inline-code {
368
+ background: rgba(255, 255, 255, 0.06);
369
+ padding: 2px 6px;
370
+ border-radius: 4px;
371
+ font-family: 'JetBrains Mono', monospace;
372
+ font-size: 0.9em;
373
+ color: ${t.badge};
374
+ }
375
+
376
+ .aeo-rendered .aeo-r-link {
377
+ color: ${t.badge};
378
+ text-decoration: none;
379
+ border-bottom: 1px solid rgba(74, 222, 128, 0.3);
380
+ transition: border-color 0.15s ease;
381
+ }
382
+
383
+ .aeo-rendered .aeo-r-link:hover {
384
+ border-color: ${t.badge};
385
+ }
386
+
387
+ .aeo-rendered strong {
388
+ color: ${t.accent};
389
+ font-weight: 600;
390
+ }
391
+
392
+ .aeo-rendered em {
393
+ font-style: italic;
394
+ opacity: 0.9;
395
+ }
396
+
223
397
  /* Content area */
224
398
  .aeo-content-area {
225
399
  flex: 1;
@@ -362,7 +536,7 @@ function getStyles(theme) {
362
536
  font-size: 13px;
363
537
  opacity: 0;
364
538
  transition: all 0.3s ease;
365
- z-index: 10002;
539
+ z-index: 2147483647;
366
540
  }
367
541
 
368
542
  .aeo-toast.aeo-toast-show {
@@ -411,6 +585,17 @@ function getStyles(theme) {
411
585
  display: none;
412
586
  }
413
587
 
588
+ .aeo-view-tabs {
589
+ order: 10;
590
+ width: 100%;
591
+ justify-content: center;
592
+ }
593
+
594
+ .aeo-meta-bar {
595
+ font-size: 11px;
596
+ gap: 8px;
597
+ }
598
+
414
599
  .aeo-content-area {
415
600
  padding: 24px 16px;
416
601
  }
@@ -820,6 +1005,10 @@ var AeoWidget = class {
820
1005
  <div class="aeo-topbar">
821
1006
  ${((_a = this.config.widget) == null ? void 0 : _a.showBadge) !== false ? '<span class="aeo-badge"><span class="aeo-badge-dot"></span>LLM-READY</span>' : ""}
822
1007
  <span class="aeo-route-tab">${mdPath}</span>
1008
+ <div class="aeo-view-tabs">
1009
+ <button class="aeo-view-tab aeo-view-active" data-view="rendered">Rendered</button>
1010
+ <button class="aeo-view-tab" data-view="source">Source</button>
1011
+ </div>
823
1012
  <div class="aeo-topbar-spacer"></div>
824
1013
  <div class="aeo-topbar-actions">
825
1014
  <button class="aeo-topbar-btn aeo-copy-btn" disabled>
@@ -848,8 +1037,135 @@ var AeoWidget = class {
848
1037
  this.container.appendChild(this.overlayElement);
849
1038
  const closeBtn = this.overlayElement.querySelector(".aeo-close-btn");
850
1039
  closeBtn == null ? void 0 : closeBtn.addEventListener("click", () => this.closeOverlay());
1040
+ const viewTabs = this.overlayElement.querySelectorAll(".aeo-view-tab");
1041
+ viewTabs.forEach((tab) => {
1042
+ tab.addEventListener("click", () => {
1043
+ var _a2, _b;
1044
+ viewTabs.forEach((t) => t.classList.remove("aeo-view-active"));
1045
+ tab.classList.add("aeo-view-active");
1046
+ const view = tab.dataset.view;
1047
+ const rendered = (_a2 = this.overlayElement) == null ? void 0 : _a2.querySelector(".aeo-rendered");
1048
+ const source = (_b = this.overlayElement) == null ? void 0 : _b.querySelector(".aeo-markdown-source");
1049
+ if (rendered && source) {
1050
+ rendered.style.display = view === "rendered" ? "block" : "none";
1051
+ source.style.display = view === "source" ? "block" : "none";
1052
+ }
1053
+ });
1054
+ });
851
1055
  await this.loadContent();
852
1056
  }
1057
+ /**
1058
+ * Strip YAML frontmatter from markdown content.
1059
+ */
1060
+ stripFrontmatter(md) {
1061
+ const frontmatter = {};
1062
+ let body = md;
1063
+ if (md.startsWith("---")) {
1064
+ const endIndex = md.indexOf("---", 3);
1065
+ if (endIndex !== -1) {
1066
+ const fmBlock = md.slice(3, endIndex).trim();
1067
+ body = md.slice(endIndex + 3).trim();
1068
+ for (const line of fmBlock.split("\n")) {
1069
+ const colonIdx = line.indexOf(":");
1070
+ if (colonIdx > 0) {
1071
+ const key = line.slice(0, colonIdx).trim();
1072
+ const val = line.slice(colonIdx + 1).trim().replace(/^["']|["']$/g, "");
1073
+ frontmatter[key] = val;
1074
+ }
1075
+ }
1076
+ }
1077
+ }
1078
+ return { frontmatter, body };
1079
+ }
1080
+ /**
1081
+ * Convert markdown to simple rendered HTML for the "Rendered" view.
1082
+ */
1083
+ renderMarkdown(md) {
1084
+ const esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1085
+ const lines = md.split("\n");
1086
+ const html = [];
1087
+ let inList = false;
1088
+ let inCode = false;
1089
+ let codeContent = [];
1090
+ for (const line of lines) {
1091
+ const trimmed = line.trim();
1092
+ if (trimmed.startsWith("```")) {
1093
+ if (inCode) {
1094
+ html.push(`<pre class="aeo-r-code"><code>${esc(codeContent.join("\n"))}</code></pre>`);
1095
+ codeContent = [];
1096
+ inCode = false;
1097
+ } else {
1098
+ if (inList) {
1099
+ html.push("</ul>");
1100
+ inList = false;
1101
+ }
1102
+ inCode = true;
1103
+ }
1104
+ continue;
1105
+ }
1106
+ if (inCode) {
1107
+ codeContent.push(line);
1108
+ continue;
1109
+ }
1110
+ if (!trimmed) {
1111
+ if (inList) {
1112
+ html.push("</ul>");
1113
+ inList = false;
1114
+ }
1115
+ continue;
1116
+ }
1117
+ const headingMatch = trimmed.match(/^(#{1,6})\s+(.*)/);
1118
+ if (headingMatch) {
1119
+ if (inList) {
1120
+ html.push("</ul>");
1121
+ inList = false;
1122
+ }
1123
+ const level = headingMatch[1].length;
1124
+ html.push(`<h${level} class="aeo-r-h${level}">${this.renderInlineMarkdown(esc(headingMatch[2]))}</h${level}>`);
1125
+ continue;
1126
+ }
1127
+ if (/^(-{3,}|\*{3,}|_{3,})$/.test(trimmed)) {
1128
+ if (inList) {
1129
+ html.push("</ul>");
1130
+ inList = false;
1131
+ }
1132
+ html.push('<hr class="aeo-r-hr">');
1133
+ continue;
1134
+ }
1135
+ if (trimmed.startsWith(">")) {
1136
+ if (inList) {
1137
+ html.push("</ul>");
1138
+ inList = false;
1139
+ }
1140
+ html.push(`<blockquote class="aeo-r-quote">${this.renderInlineMarkdown(esc(trimmed.slice(1).trim()))}</blockquote>`);
1141
+ continue;
1142
+ }
1143
+ const listMatch = trimmed.match(/^[-*+]\s+(.*)/);
1144
+ if (listMatch) {
1145
+ if (!inList) {
1146
+ html.push('<ul class="aeo-r-list">');
1147
+ inList = true;
1148
+ }
1149
+ html.push(`<li>${this.renderInlineMarkdown(esc(listMatch[1]))}</li>`);
1150
+ continue;
1151
+ }
1152
+ if (inList) {
1153
+ html.push("</ul>");
1154
+ inList = false;
1155
+ }
1156
+ html.push(`<p class="aeo-r-p">${this.renderInlineMarkdown(esc(trimmed))}</p>`);
1157
+ }
1158
+ if (inList) html.push("</ul>");
1159
+ if (inCode) html.push(`<pre class="aeo-r-code"><code>${esc(codeContent.join("\n"))}</code></pre>`);
1160
+ return html.join("\n");
1161
+ }
1162
+ renderInlineMarkdown(text) {
1163
+ let out = text.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
1164
+ out = out.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g, "<em>$1</em>");
1165
+ out = out.replace(/`([^`]+)`/g, '<code class="aeo-r-inline-code">$1</code>');
1166
+ out = out.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a class="aeo-r-link" href="$2" target="_blank" rel="noopener">$1</a>');
1167
+ return out;
1168
+ }
853
1169
  async loadContent() {
854
1170
  if (!this.overlayElement) return;
855
1171
  const wrapper = this.overlayElement.querySelector(".aeo-content-wrapper");
@@ -863,8 +1179,15 @@ var AeoWidget = class {
863
1179
  } else {
864
1180
  content = extractDOMToMarkdown();
865
1181
  }
1182
+ const { frontmatter, body } = this.stripFrontmatter(content);
1183
+ const metaItems = [];
1184
+ if (frontmatter.title) metaItems.push(`<span class="aeo-meta-label">Title:</span> ${this.escHtml(frontmatter.title)}`);
1185
+ if (frontmatter.url) metaItems.push(`<span class="aeo-meta-label">URL:</span> <a class="aeo-r-link" href="${this.escHtml(frontmatter.url)}" target="_blank">${this.escHtml(frontmatter.url)}</a>`);
1186
+ const metaBar = metaItems.length > 0 ? `<div class="aeo-meta-bar">${metaItems.join('<span class="aeo-meta-sep"></span>')}</div>` : "";
866
1187
  wrapper.innerHTML = `
867
- <pre class="aeo-markdown-source"><code>${this.highlightMarkdown(content)}</code></pre>
1188
+ ${metaBar}
1189
+ <div class="aeo-rendered">${this.renderMarkdown(body)}</div>
1190
+ <pre class="aeo-markdown-source" style="display:none"><code>${this.highlightMarkdown(content)}</code></pre>
868
1191
  `;
869
1192
  const copyBtn = this.overlayElement.querySelector(".aeo-copy-btn");
870
1193
  const downloadBtn = this.overlayElement.querySelector(".aeo-download-btn");
@@ -889,6 +1212,9 @@ var AeoWidget = class {
889
1212
  `;
890
1213
  }
891
1214
  }
1215
+ escHtml(s) {
1216
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1217
+ }
892
1218
  highlightMarkdown(md) {
893
1219
  var _a;
894
1220
  const esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");