eyeling 1.24.11 → 1.24.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.24.11",
3
+ "version": "1.24.13",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [
@@ -646,11 +646,23 @@ async function main() {
646
646
  };
647
647
  })
648
648
  : [];
649
+ const renderedPanel = document.getElementById('output-rendered');
650
+ const renderedTab = document.getElementById('output-rendered-tab');
651
+ const sourceTab = document.getElementById('output-source-tab');
652
+ const sourceWrapper = document.getElementById('output-source');
649
653
  return {
650
654
  status: statusEl ? String(statusEl.textContent || '') : '',
651
655
  output: outputCm && typeof outputCm.getValue === 'function'
652
656
  ? String(outputCm.getValue() || '')
653
657
  : (outputTa ? String(outputTa.value || '') : ''),
658
+ renderedText: renderedPanel ? String(renderedPanel.textContent || '') : '',
659
+ renderedHtml: renderedPanel ? String(renderedPanel.innerHTML || '') : '',
660
+ renderedHidden: renderedPanel ? !!renderedPanel.hidden : true,
661
+ sourceHidden: sourceWrapper ? sourceWrapper.classList.contains('markdown-source-hidden') : true,
662
+ renderedTabSelected: renderedTab ? renderedTab.getAttribute('aria-selected') === 'true' : false,
663
+ sourceTabSelected: sourceTab ? sourceTab.getAttribute('aria-selected') === 'true' : false,
664
+ shareStatus: document.getElementById('share-status') ? String(document.getElementById('share-status').textContent || '') : '',
665
+ href: String(window.location.href || ''),
654
666
  highlighted,
655
667
  };
656
668
  })()`)) || { status: '', output: '', highlighted: [] }
@@ -681,6 +693,28 @@ async function main() {
681
693
  })()`);
682
694
  }
683
695
 
696
+ async function clickOutputSourceTab() {
697
+ await evalInPage(`(() => {
698
+ const btn = document.getElementById('output-source-tab');
699
+ if (!btn) throw new Error('output-source-tab not found');
700
+ btn.click();
701
+ return true;
702
+ })()`);
703
+ }
704
+
705
+ async function clickOutputRenderedTab() {
706
+ await evalInPage(`(() => {
707
+ const btn = document.getElementById('output-rendered-tab');
708
+ if (!btn) throw new Error('output-rendered-tab not found');
709
+ btn.click();
710
+ return true;
711
+ })()`);
712
+ }
713
+
714
+ async function makeShareUrlInPage() {
715
+ return await evalInPage(`window.__eyelingPlaygroundMakeShareUrl()`);
716
+ }
717
+
684
718
  async function loadUrlIntoEditor(url) {
685
719
  const payload = JSON.stringify(String(url));
686
720
  await evalInPage(`(() => {
@@ -720,7 +754,7 @@ ${JSON.stringify(last, null, 2)}`);
720
754
  const fuseProgram = fs.readFileSync(path.join(ROOT, 'examples', 'fuse.n3'), 'utf8');
721
755
  const outputStringProgram = `@prefix : <#> .
722
756
  @prefix log: <http://www.w3.org/2000/10/swap/log#> .
723
- :report log:outputString "Hello from output string\nLine 2\n" .
757
+ :report log:outputString "## Hello from output string\n\nLine 2 with **bold** and [Eyeling](https://example.org/eyeling)\n" .
724
758
  `;
725
759
 
726
760
  // 1) Baseline smoke test: the default program runs to completion.
@@ -778,21 +812,50 @@ ${JSON.stringify(last, null, 2)}`);
778
812
  .startsWith('Done') && /Hello from output string/.test(String(st.output || '')),
779
813
  20000,
780
814
  );
781
- assert.match(rendered.output, /^Hello from output string\nLine 2\n?$/m, 'Expected rendered outputString text');
815
+ assert.match(rendered.output, /^## Hello from output string\n\nLine 2 with \*\*bold\*\*/m, 'Expected markdown source output');
782
816
  assert.doesNotMatch(
783
817
  rendered.output,
784
818
  /:report\s+log:outputString\s+"|# Derived triples/i,
785
819
  'Expected clean rendered output without raw triples',
786
820
  );
787
- ok('playground renders log:outputString cleanly in Output');
788
-
789
- // 5) URL-loaded repository examples should auto-load matching examples/builtin/<stem>.js.
821
+ assert.equal(rendered.renderedHidden, false, 'Expected rendered Markdown tab to be visible by default');
822
+ assert.equal(rendered.sourceHidden, true, 'Expected Markdown source tab to be hidden by default');
823
+ assert.equal(rendered.renderedTabSelected, true, 'Expected Rendered tab to be selected by default');
824
+ assert.match(rendered.renderedText, /Hello from output string/, 'Expected rendered Markdown text');
825
+ assert.match(rendered.renderedHtml, /<h2>Hello from output string<\/h2>/i, 'Expected Markdown heading rendering');
826
+ assert.match(rendered.renderedHtml, /<strong>bold<\/strong>/i, 'Expected Markdown bold rendering');
827
+ assert.match(rendered.renderedHtml, /href="https:\/\/example\.org\/eyeling"/i, 'Expected Markdown link rendering');
828
+
829
+ await clickOutputSourceTab();
830
+ const sourceView = await getPlaygroundState();
831
+ assert.equal(sourceView.sourceTabSelected, true, 'Expected Markdown source tab to be selectable');
832
+ assert.equal(sourceView.renderedHidden, true, 'Expected rendered Markdown panel to hide after selecting source');
833
+ assert.equal(sourceView.sourceHidden, false, 'Expected source editor to show after selecting source');
834
+ assert.match(sourceView.output, /^## Hello from output string/m, 'Expected source tab to show markdown source');
835
+
836
+ await clickOutputRenderedTab();
837
+ const renderedAgain = await getPlaygroundState();
838
+ assert.equal(renderedAgain.renderedTabSelected, true, 'Expected Rendered tab to be selectable again');
839
+ ok('playground renders log:outputString Markdown with Rendered/Markdown source tabs');
840
+
841
+ // 5) Normal editing should not keep rewriting the browser URL with raw N3 content.
842
+ assert.doesNotMatch(renderedAgain.href, /[?&](?:edit|program)=/, 'Expected live URL to avoid raw editor content');
843
+ const compactShareUrl = await makeShareUrlInPage();
844
+ assert.match(compactShareUrl, /[?&]state=/, 'Expected an on-demand compact state parameter');
845
+ assert.doesNotMatch(compactShareUrl, /[?&](?:edit|program)=/, 'Expected share link to avoid raw edit/program params');
846
+ assert.ok(compactShareUrl.length < playgroundUrl.length + encodeURIComponent(outputStringProgram).length, 'Expected compact share URL to be shorter than raw editor URL');
847
+ ok('playground keeps the live URL short and creates compact share links on demand');
848
+
849
+ // 6) URL-loaded repository examples should auto-load matching examples/builtin/<stem>.js.
790
850
  await loadUrlIntoEditor('https://raw.githubusercontent.com/eyereasoner/eyeling/refs/heads/main/examples/sudoku.n3');
791
851
  await waitForState(
792
852
  'sudoku URL loaded with companion builtin',
793
853
  (st) => /loaded n3 into the editor and loaded its example builtin/i.test(String(st.status || '')),
794
854
  20000,
795
855
  );
856
+ const urlLoadedShareUrl = await makeShareUrlInPage();
857
+ assert.match(urlLoadedShareUrl, /[?&]url=/, 'Expected URL-loaded examples to share as a short url= link');
858
+ assert.doesNotMatch(urlLoadedShareUrl, /[?&]state=/, 'Expected unedited URL-loaded examples to avoid state payloads');
796
859
  await clickRun();
797
860
  const sudoku = await waitForState(
798
861
  'URL-loaded Sudoku example completion',