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