Fossil SCM
Add a experimental 'open in /pikchrshow' link beneath the source code view of rendered pikchrs. This has only been tested in the forum view and needs further experimentation, and perhaps a way to disable it, in other views.
Commit
ca27e6917904d5d14ccb36954e9b62099083eaf8f0e964e55f2974851d1ac43b
Parent
0dcce257b04e2bf…
4 files changed
+22
-6
+15
-3
+26
-1
+11
-2
+22
-6
| --- src/default.css | ||
| +++ src/default.css | ||
| @@ -1681,22 +1681,38 @@ | ||
| 1681 | 1681 | DOM structure: |
| 1682 | 1682 | <DIV.pikchr-wrapper> |
| 1683 | 1683 | <DIV.pikchr-svg> |
| 1684 | 1684 | <SVG.pikchr>...</SVG> |
| 1685 | 1685 | </DIV.pikchr-svg> |
| 1686 | - <PRE.pikchr-src>...</PRE> | |
| 1686 | + <DIV.pikchr-src> | |
| 1687 | + <PRE>pikchr source code</PRE> | |
| 1688 | + <SPAN class='hidden'><A>link to open pikchr in /pikchrshow</A></SPAN> | |
| 1689 | + <!-- ^^^ is unhidden and activated by JS code --> | |
| 1690 | + </DIV.pikchr-src> | |
| 1687 | 1691 | </DIV.pikchr-wrapper> |
| 1688 | 1692 | |
| 1689 | 1693 | ************************************************************/ |
| 1690 | 1694 | div.pikchr-wrapper {/*outer wrapper elem for a pikchr construct*/} |
| 1691 | 1695 | div.pikchr-svg {/*wrapper for SVG.pikchr element*/} |
| 1692 | 1696 | svg.pikchr {/*pikchr SVG*/ |
| 1693 | 1697 | width: 100%/*necessary for SOME SVGs for Chrome!*/; |
| 1694 | 1698 | } |
| 1695 | -pre.pikchr-src {/*source code view for a pikchr (see fossil.pikchr.js)*/ | |
| 1699 | + | |
| 1700 | +div.pikchr-src { | |
| 1701 | + /*Wrapper for source code view of a pikchr (see fossil.pikchr.js)*/ | |
| 1702 | + display: flex; | |
| 1703 | + flex-direction: column; | |
| 1704 | +} | |
| 1705 | +div.pikchr-src > pre { | |
| 1706 | + /*Source code for a pikchr*/ | |
| 1696 | 1707 | box-sizing: border-box; |
| 1697 | 1708 | text-align: left; |
| 1709 | +} | |
| 1710 | +div.pikchr-src > span { | |
| 1711 | + /*Wrapper for a link to open a pikchr in /pikchrshow*/ | |
| 1712 | + margin-top: 0.8em; | |
| 1713 | + font-size: 80%; | |
| 1698 | 1714 | } |
| 1699 | 1715 | /* The .source-inline class tells the .source class that the |
| 1700 | 1716 | source view, when enabled, should be "inline" (same position |
| 1701 | 1717 | as the graphic), else the sources are shifted to the left as |
| 1702 | 1718 | if they were "plain text". */ |
| @@ -1712,14 +1728,14 @@ | ||
| 1712 | 1728 | still-seemingly-legitimate browsers don't support grid mode. */ |
| 1713 | 1729 | } |
| 1714 | 1730 | div.pikchr-wrapper.center > div.pikchr-svg { |
| 1715 | 1731 | width: 100%/*necessary for Chrome!*/; |
| 1716 | 1732 | } |
| 1717 | -div.pikchr-wrapper.center:not(.source) > pre.pikchr-src, | |
| 1733 | +div.pikchr-wrapper.center:not(.source) > div.pikchr-src, | |
| 1718 | 1734 | div.pikchr-wrapper.center:not(.source) > div.pikchr-svg, |
| 1719 | 1735 | /* ^^^ Centered non-source-view elements */ |
| 1720 | -div.pikchr-wrapper.center.source.source-inline > pre.pikchr-src, | |
| 1736 | +div.pikchr-wrapper.center.source.source-inline div.pikchr-src, | |
| 1721 | 1737 | div.pikchr-wrapper.center.source.source-inline > div.pikchr-svg |
| 1722 | 1738 | /* ^^^ Centered inline-source-view elements */{ |
| 1723 | 1739 | display:inline-block/*allows parent text-align to do the alignment*/; |
| 1724 | 1740 | /* ^^^^ Browser incompatibility: inline-block causes the centered |
| 1725 | 1741 | pikchr to shrink to the point of illegiblity in Chrome. The |
| @@ -1743,14 +1759,14 @@ | ||
| 1743 | 1759 | padding: 4em; |
| 1744 | 1760 | } |
| 1745 | 1761 | |
| 1746 | 1762 | /* For pikchr-wrapper.source mode, toggle pre.pikchr-src and |
| 1747 | 1763 | svg.pikchr visibility... */ |
| 1748 | -div.pikchr-wrapper.source > pre.pikchr-src { | |
| 1764 | +div.pikchr-wrapper.source > div.pikchr-src { | |
| 1749 | 1765 | /* Source code ^^^^^^^ is visible, else it is hidden */ |
| 1750 | 1766 | } |
| 1751 | -div.pikchr-wrapper:not(.source) > pre.pikchr-src { | |
| 1767 | +div.pikchr-wrapper:not(.source) > div.pikchr-src { | |
| 1752 | 1768 | /* Hide sources when image is being shown. */ |
| 1753 | 1769 | position: absolute !important; |
| 1754 | 1770 | opacity: 0 !important; |
| 1755 | 1771 | pointer-events: none !important; |
| 1756 | 1772 | display: none !important; |
| 1757 | 1773 |
| --- src/default.css | |
| +++ src/default.css | |
| @@ -1681,22 +1681,38 @@ | |
| 1681 | DOM structure: |
| 1682 | <DIV.pikchr-wrapper> |
| 1683 | <DIV.pikchr-svg> |
| 1684 | <SVG.pikchr>...</SVG> |
| 1685 | </DIV.pikchr-svg> |
| 1686 | <PRE.pikchr-src>...</PRE> |
| 1687 | </DIV.pikchr-wrapper> |
| 1688 | |
| 1689 | ************************************************************/ |
| 1690 | div.pikchr-wrapper {/*outer wrapper elem for a pikchr construct*/} |
| 1691 | div.pikchr-svg {/*wrapper for SVG.pikchr element*/} |
| 1692 | svg.pikchr {/*pikchr SVG*/ |
| 1693 | width: 100%/*necessary for SOME SVGs for Chrome!*/; |
| 1694 | } |
| 1695 | pre.pikchr-src {/*source code view for a pikchr (see fossil.pikchr.js)*/ |
| 1696 | box-sizing: border-box; |
| 1697 | text-align: left; |
| 1698 | } |
| 1699 | /* The .source-inline class tells the .source class that the |
| 1700 | source view, when enabled, should be "inline" (same position |
| 1701 | as the graphic), else the sources are shifted to the left as |
| 1702 | if they were "plain text". */ |
| @@ -1712,14 +1728,14 @@ | |
| 1712 | still-seemingly-legitimate browsers don't support grid mode. */ |
| 1713 | } |
| 1714 | div.pikchr-wrapper.center > div.pikchr-svg { |
| 1715 | width: 100%/*necessary for Chrome!*/; |
| 1716 | } |
| 1717 | div.pikchr-wrapper.center:not(.source) > pre.pikchr-src, |
| 1718 | div.pikchr-wrapper.center:not(.source) > div.pikchr-svg, |
| 1719 | /* ^^^ Centered non-source-view elements */ |
| 1720 | div.pikchr-wrapper.center.source.source-inline > pre.pikchr-src, |
| 1721 | div.pikchr-wrapper.center.source.source-inline > div.pikchr-svg |
| 1722 | /* ^^^ Centered inline-source-view elements */{ |
| 1723 | display:inline-block/*allows parent text-align to do the alignment*/; |
| 1724 | /* ^^^^ Browser incompatibility: inline-block causes the centered |
| 1725 | pikchr to shrink to the point of illegiblity in Chrome. The |
| @@ -1743,14 +1759,14 @@ | |
| 1743 | padding: 4em; |
| 1744 | } |
| 1745 | |
| 1746 | /* For pikchr-wrapper.source mode, toggle pre.pikchr-src and |
| 1747 | svg.pikchr visibility... */ |
| 1748 | div.pikchr-wrapper.source > pre.pikchr-src { |
| 1749 | /* Source code ^^^^^^^ is visible, else it is hidden */ |
| 1750 | } |
| 1751 | div.pikchr-wrapper:not(.source) > pre.pikchr-src { |
| 1752 | /* Hide sources when image is being shown. */ |
| 1753 | position: absolute !important; |
| 1754 | opacity: 0 !important; |
| 1755 | pointer-events: none !important; |
| 1756 | display: none !important; |
| 1757 |
| --- src/default.css | |
| +++ src/default.css | |
| @@ -1681,22 +1681,38 @@ | |
| 1681 | DOM structure: |
| 1682 | <DIV.pikchr-wrapper> |
| 1683 | <DIV.pikchr-svg> |
| 1684 | <SVG.pikchr>...</SVG> |
| 1685 | </DIV.pikchr-svg> |
| 1686 | <DIV.pikchr-src> |
| 1687 | <PRE>pikchr source code</PRE> |
| 1688 | <SPAN class='hidden'><A>link to open pikchr in /pikchrshow</A></SPAN> |
| 1689 | <!-- ^^^ is unhidden and activated by JS code --> |
| 1690 | </DIV.pikchr-src> |
| 1691 | </DIV.pikchr-wrapper> |
| 1692 | |
| 1693 | ************************************************************/ |
| 1694 | div.pikchr-wrapper {/*outer wrapper elem for a pikchr construct*/} |
| 1695 | div.pikchr-svg {/*wrapper for SVG.pikchr element*/} |
| 1696 | svg.pikchr {/*pikchr SVG*/ |
| 1697 | width: 100%/*necessary for SOME SVGs for Chrome!*/; |
| 1698 | } |
| 1699 | |
| 1700 | div.pikchr-src { |
| 1701 | /*Wrapper for source code view of a pikchr (see fossil.pikchr.js)*/ |
| 1702 | display: flex; |
| 1703 | flex-direction: column; |
| 1704 | } |
| 1705 | div.pikchr-src > pre { |
| 1706 | /*Source code for a pikchr*/ |
| 1707 | box-sizing: border-box; |
| 1708 | text-align: left; |
| 1709 | } |
| 1710 | div.pikchr-src > span { |
| 1711 | /*Wrapper for a link to open a pikchr in /pikchrshow*/ |
| 1712 | margin-top: 0.8em; |
| 1713 | font-size: 80%; |
| 1714 | } |
| 1715 | /* The .source-inline class tells the .source class that the |
| 1716 | source view, when enabled, should be "inline" (same position |
| 1717 | as the graphic), else the sources are shifted to the left as |
| 1718 | if they were "plain text". */ |
| @@ -1712,14 +1728,14 @@ | |
| 1728 | still-seemingly-legitimate browsers don't support grid mode. */ |
| 1729 | } |
| 1730 | div.pikchr-wrapper.center > div.pikchr-svg { |
| 1731 | width: 100%/*necessary for Chrome!*/; |
| 1732 | } |
| 1733 | div.pikchr-wrapper.center:not(.source) > div.pikchr-src, |
| 1734 | div.pikchr-wrapper.center:not(.source) > div.pikchr-svg, |
| 1735 | /* ^^^ Centered non-source-view elements */ |
| 1736 | div.pikchr-wrapper.center.source.source-inline div.pikchr-src, |
| 1737 | div.pikchr-wrapper.center.source.source-inline > div.pikchr-svg |
| 1738 | /* ^^^ Centered inline-source-view elements */{ |
| 1739 | display:inline-block/*allows parent text-align to do the alignment*/; |
| 1740 | /* ^^^^ Browser incompatibility: inline-block causes the centered |
| 1741 | pikchr to shrink to the point of illegiblity in Chrome. The |
| @@ -1743,14 +1759,14 @@ | |
| 1759 | padding: 4em; |
| 1760 | } |
| 1761 | |
| 1762 | /* For pikchr-wrapper.source mode, toggle pre.pikchr-src and |
| 1763 | svg.pikchr visibility... */ |
| 1764 | div.pikchr-wrapper.source > div.pikchr-src { |
| 1765 | /* Source code ^^^^^^^ is visible, else it is hidden */ |
| 1766 | } |
| 1767 | div.pikchr-wrapper:not(.source) > div.pikchr-src { |
| 1768 | /* Hide sources when image is being shown. */ |
| 1769 | position: absolute !important; |
| 1770 | opacity: 0 !important; |
| 1771 | pointer-events: none !important; |
| 1772 | display: none !important; |
| 1773 |
+15
-3
| --- src/fossil.page.pikchrshowasm.js | ||
| +++ src/fossil.page.pikchrshowasm.js | ||
| @@ -206,11 +206,11 @@ | ||
| 206 | 206 | const text = getCurrentText(); |
| 207 | 207 | if(text) PS.render(text); |
| 208 | 208 | }; |
| 209 | 209 | const setCurrentText = function(txt){ |
| 210 | 210 | taInput.value = txt; |
| 211 | - renderCurrentText(); | |
| 211 | + renderCurrentText(); | |
| 212 | 212 | }; |
| 213 | 213 | PS.e.btnRender.addEventListener('click',function(ev){ |
| 214 | 214 | ev.preventDefault(); |
| 215 | 215 | renderCurrentText(); |
| 216 | 216 | },false); |
| @@ -427,13 +427,25 @@ | ||
| 427 | 427 | btnToggle.addEventListener('click', function(){ |
| 428 | 428 | fs.classList.toggle('collapsed'); |
| 429 | 429 | content.forEach((d)=>d.classList.toggle('hidden')); |
| 430 | 430 | }, false); |
| 431 | 431 | }); |
| 432 | + | |
| 433 | + if(window.sessionStorage){ | |
| 434 | + /* If sessionStorage['pikchr-xfer'] exists and the "fromSession" | |
| 435 | + URL argument was passed to this page, load the pikchr source | |
| 436 | + from the session. This is used by the "open in pikchrshow" | |
| 437 | + link in the forum. */ | |
| 438 | + const src = window.sessionStorage.getItem('pikchr-xfer'); | |
| 439 | + if( src && (new URL(self.location.href).searchParams).has('fromSession') ){ | |
| 440 | + taInput.value = src; | |
| 441 | + window.sessionStorage.removeItem('pikchr-xfer'); | |
| 442 | + } | |
| 443 | + } | |
| 432 | 444 | |
| 433 | 445 | PS.e.btnRender.click(); |
| 434 | - | |
| 446 | + | |
| 435 | 447 | /** Debounce handler for auto-rendering while typing. */ |
| 436 | 448 | const debounceAutoRender = F.debounce(function f(){ |
| 437 | 449 | if(!PS._isDirty) return; |
| 438 | 450 | const text = getCurrentText(); |
| 439 | 451 | if(f._ === text){ |
| @@ -618,11 +630,11 @@ | ||
| 618 | 630 | "Darlene" above aligned |
| 619 | 631 | |
| 620 | 632 | # fill in content for the Alice lane |
| 621 | 633 | right |
| 622 | 634 | A1: circle rad 0.1in at end of first line + (0.2,-0.2) \ |
| 623 | - fill white thickness 1.5px "1" | |
| 635 | + fill white thickness 1.5px "1" | |
| 624 | 636 | arrow right 50% |
| 625 | 637 | circle same "2" |
| 626 | 638 | arrow right until even with first box.e - (0.65,0.0) |
| 627 | 639 | ellipse "future" fit fill white height 0.2 width 0.5 thickness 1.5px |
| 628 | 640 | A3: circle same at A1+(0.8,-0.3) "3" fill 0xc0c0c0 |
| 629 | 641 |
| --- src/fossil.page.pikchrshowasm.js | |
| +++ src/fossil.page.pikchrshowasm.js | |
| @@ -206,11 +206,11 @@ | |
| 206 | const text = getCurrentText(); |
| 207 | if(text) PS.render(text); |
| 208 | }; |
| 209 | const setCurrentText = function(txt){ |
| 210 | taInput.value = txt; |
| 211 | renderCurrentText(); |
| 212 | }; |
| 213 | PS.e.btnRender.addEventListener('click',function(ev){ |
| 214 | ev.preventDefault(); |
| 215 | renderCurrentText(); |
| 216 | },false); |
| @@ -427,13 +427,25 @@ | |
| 427 | btnToggle.addEventListener('click', function(){ |
| 428 | fs.classList.toggle('collapsed'); |
| 429 | content.forEach((d)=>d.classList.toggle('hidden')); |
| 430 | }, false); |
| 431 | }); |
| 432 | |
| 433 | PS.e.btnRender.click(); |
| 434 | |
| 435 | /** Debounce handler for auto-rendering while typing. */ |
| 436 | const debounceAutoRender = F.debounce(function f(){ |
| 437 | if(!PS._isDirty) return; |
| 438 | const text = getCurrentText(); |
| 439 | if(f._ === text){ |
| @@ -618,11 +630,11 @@ | |
| 618 | "Darlene" above aligned |
| 619 | |
| 620 | # fill in content for the Alice lane |
| 621 | right |
| 622 | A1: circle rad 0.1in at end of first line + (0.2,-0.2) \ |
| 623 | fill white thickness 1.5px "1" |
| 624 | arrow right 50% |
| 625 | circle same "2" |
| 626 | arrow right until even with first box.e - (0.65,0.0) |
| 627 | ellipse "future" fit fill white height 0.2 width 0.5 thickness 1.5px |
| 628 | A3: circle same at A1+(0.8,-0.3) "3" fill 0xc0c0c0 |
| 629 |
| --- src/fossil.page.pikchrshowasm.js | |
| +++ src/fossil.page.pikchrshowasm.js | |
| @@ -206,11 +206,11 @@ | |
| 206 | const text = getCurrentText(); |
| 207 | if(text) PS.render(text); |
| 208 | }; |
| 209 | const setCurrentText = function(txt){ |
| 210 | taInput.value = txt; |
| 211 | renderCurrentText(); |
| 212 | }; |
| 213 | PS.e.btnRender.addEventListener('click',function(ev){ |
| 214 | ev.preventDefault(); |
| 215 | renderCurrentText(); |
| 216 | },false); |
| @@ -427,13 +427,25 @@ | |
| 427 | btnToggle.addEventListener('click', function(){ |
| 428 | fs.classList.toggle('collapsed'); |
| 429 | content.forEach((d)=>d.classList.toggle('hidden')); |
| 430 | }, false); |
| 431 | }); |
| 432 | |
| 433 | if(window.sessionStorage){ |
| 434 | /* If sessionStorage['pikchr-xfer'] exists and the "fromSession" |
| 435 | URL argument was passed to this page, load the pikchr source |
| 436 | from the session. This is used by the "open in pikchrshow" |
| 437 | link in the forum. */ |
| 438 | const src = window.sessionStorage.getItem('pikchr-xfer'); |
| 439 | if( src && (new URL(self.location.href).searchParams).has('fromSession') ){ |
| 440 | taInput.value = src; |
| 441 | window.sessionStorage.removeItem('pikchr-xfer'); |
| 442 | } |
| 443 | } |
| 444 | |
| 445 | PS.e.btnRender.click(); |
| 446 | |
| 447 | /** Debounce handler for auto-rendering while typing. */ |
| 448 | const debounceAutoRender = F.debounce(function f(){ |
| 449 | if(!PS._isDirty) return; |
| 450 | const text = getCurrentText(); |
| 451 | if(f._ === text){ |
| @@ -618,11 +630,11 @@ | |
| 630 | "Darlene" above aligned |
| 631 | |
| 632 | # fill in content for the Alice lane |
| 633 | right |
| 634 | A1: circle rad 0.1in at end of first line + (0.2,-0.2) \ |
| 635 | fill white thickness 1.5px "1" |
| 636 | arrow right 50% |
| 637 | circle same "2" |
| 638 | arrow right until even with first box.e - (0.65,0.0) |
| 639 | ellipse "future" fit fill white height 0.2 width 0.5 thickness 1.5px |
| 640 | A3: circle same at A1+(0.8,-0.3) "3" fill 0xc0c0c0 |
| 641 |
+26
-1
| --- src/fossil.pikchr.js | ||
| +++ src/fossil.pikchr.js | ||
| @@ -38,11 +38,14 @@ | ||
| 38 | 38 | This code expects the following structure around the SVGs, and |
| 39 | 39 | will not process any which don't match this: |
| 40 | 40 | |
| 41 | 41 | <DIV.pikchr-wrapper> |
| 42 | 42 | <DIV.pikchr-svg><SVG.pikchr></SVG></DIV> |
| 43 | - <PRE.pikchr-src></PRE> | |
| 43 | + <DIV.pikchr-src> | |
| 44 | + <PRE>pikchr source code</PRE> | |
| 45 | + <SPAN class='hidden'><A>link to open pikchr in /pikchrshow</A></SPAN> | |
| 46 | + </DIV> | |
| 44 | 47 | </DIV> |
| 45 | 48 | */ |
| 46 | 49 | P.addSrcView = function f(svg){ |
| 47 | 50 | if(!f.hasOwnProperty('parentClick')){ |
| 48 | 51 | f.parentClick = function(ev){ |
| @@ -58,10 +61,24 @@ | ||
| 58 | 61 | this.classList.toggle('source'); |
| 59 | 62 | ev.stopPropagation(); |
| 60 | 63 | ev.preventDefault(); |
| 61 | 64 | } |
| 62 | 65 | }; |
| 66 | + /** | |
| 67 | + Event handler for the "open in pikchrshow" links: store the | |
| 68 | + source code for the link's pikchr in | |
| 69 | + window.sessionStorage['pikchr-xfer'] then open | |
| 70 | + /pikchrshow?fromSession to trigger loading of that pikchr. | |
| 71 | + */ | |
| 72 | + f.clickPikchrShow = function(ev){ | |
| 73 | + const pId = this.dataset['pikchrid']; | |
| 74 | + if(!pId) return; | |
| 75 | + const ePikchr = this.parentNode.parentNode.querySelector('#'+pId); | |
| 76 | + if(!ePikchr) return; | |
| 77 | + window.sessionStorage.setItem('pikchr-xfer', ePikchr.innerText); | |
| 78 | + ev.stopPropagation() /* keep pikchr source view from toggling */; | |
| 79 | + }; | |
| 63 | 80 | }; |
| 64 | 81 | if(!svg) svg = 'svg.pikchr'; |
| 65 | 82 | if('string' === typeof svg){ |
| 66 | 83 | document.querySelectorAll(svg).forEach((e)=>f.call(this, e)); |
| 67 | 84 | return this; |
| @@ -78,8 +95,16 @@ | ||
| 78 | 95 | if(!srcView || !srcView.classList.contains('pikchr-src')){ |
| 79 | 96 | /* Without this element, there's nothing for us to do here. */ |
| 80 | 97 | return this; |
| 81 | 98 | } |
| 82 | 99 | parent.addEventListener('click', f.parentClick, false); |
| 100 | + const eSpan = srcView.querySelector('span'); | |
| 101 | + if(window.sessionStorage && eSpan){ | |
| 102 | + const openLink = eSpan.querySelector('a'); | |
| 103 | + if( openLink ){ | |
| 104 | + D.removeClass(eSpan, 'hidden'); | |
| 105 | + openLink.addEventListener('click', f.clickPikchrShow, false); | |
| 106 | + } | |
| 107 | + } | |
| 83 | 108 | return this; |
| 84 | 109 | }; |
| 85 | 110 | })(window.fossil); |
| 86 | 111 |
| --- src/fossil.pikchr.js | |
| +++ src/fossil.pikchr.js | |
| @@ -38,11 +38,14 @@ | |
| 38 | This code expects the following structure around the SVGs, and |
| 39 | will not process any which don't match this: |
| 40 | |
| 41 | <DIV.pikchr-wrapper> |
| 42 | <DIV.pikchr-svg><SVG.pikchr></SVG></DIV> |
| 43 | <PRE.pikchr-src></PRE> |
| 44 | </DIV> |
| 45 | */ |
| 46 | P.addSrcView = function f(svg){ |
| 47 | if(!f.hasOwnProperty('parentClick')){ |
| 48 | f.parentClick = function(ev){ |
| @@ -58,10 +61,24 @@ | |
| 58 | this.classList.toggle('source'); |
| 59 | ev.stopPropagation(); |
| 60 | ev.preventDefault(); |
| 61 | } |
| 62 | }; |
| 63 | }; |
| 64 | if(!svg) svg = 'svg.pikchr'; |
| 65 | if('string' === typeof svg){ |
| 66 | document.querySelectorAll(svg).forEach((e)=>f.call(this, e)); |
| 67 | return this; |
| @@ -78,8 +95,16 @@ | |
| 78 | if(!srcView || !srcView.classList.contains('pikchr-src')){ |
| 79 | /* Without this element, there's nothing for us to do here. */ |
| 80 | return this; |
| 81 | } |
| 82 | parent.addEventListener('click', f.parentClick, false); |
| 83 | return this; |
| 84 | }; |
| 85 | })(window.fossil); |
| 86 |
| --- src/fossil.pikchr.js | |
| +++ src/fossil.pikchr.js | |
| @@ -38,11 +38,14 @@ | |
| 38 | This code expects the following structure around the SVGs, and |
| 39 | will not process any which don't match this: |
| 40 | |
| 41 | <DIV.pikchr-wrapper> |
| 42 | <DIV.pikchr-svg><SVG.pikchr></SVG></DIV> |
| 43 | <DIV.pikchr-src> |
| 44 | <PRE>pikchr source code</PRE> |
| 45 | <SPAN class='hidden'><A>link to open pikchr in /pikchrshow</A></SPAN> |
| 46 | </DIV> |
| 47 | </DIV> |
| 48 | */ |
| 49 | P.addSrcView = function f(svg){ |
| 50 | if(!f.hasOwnProperty('parentClick')){ |
| 51 | f.parentClick = function(ev){ |
| @@ -58,10 +61,24 @@ | |
| 61 | this.classList.toggle('source'); |
| 62 | ev.stopPropagation(); |
| 63 | ev.preventDefault(); |
| 64 | } |
| 65 | }; |
| 66 | /** |
| 67 | Event handler for the "open in pikchrshow" links: store the |
| 68 | source code for the link's pikchr in |
| 69 | window.sessionStorage['pikchr-xfer'] then open |
| 70 | /pikchrshow?fromSession to trigger loading of that pikchr. |
| 71 | */ |
| 72 | f.clickPikchrShow = function(ev){ |
| 73 | const pId = this.dataset['pikchrid']; |
| 74 | if(!pId) return; |
| 75 | const ePikchr = this.parentNode.parentNode.querySelector('#'+pId); |
| 76 | if(!ePikchr) return; |
| 77 | window.sessionStorage.setItem('pikchr-xfer', ePikchr.innerText); |
| 78 | ev.stopPropagation() /* keep pikchr source view from toggling */; |
| 79 | }; |
| 80 | }; |
| 81 | if(!svg) svg = 'svg.pikchr'; |
| 82 | if('string' === typeof svg){ |
| 83 | document.querySelectorAll(svg).forEach((e)=>f.call(this, e)); |
| 84 | return this; |
| @@ -78,8 +95,16 @@ | |
| 95 | if(!srcView || !srcView.classList.contains('pikchr-src')){ |
| 96 | /* Without this element, there's nothing for us to do here. */ |
| 97 | return this; |
| 98 | } |
| 99 | parent.addEventListener('click', f.parentClick, false); |
| 100 | const eSpan = srcView.querySelector('span'); |
| 101 | if(window.sessionStorage && eSpan){ |
| 102 | const openLink = eSpan.querySelector('a'); |
| 103 | if( openLink ){ |
| 104 | D.removeClass(eSpan, 'hidden'); |
| 105 | openLink.addEventListener('click', f.clickPikchrShow, false); |
| 106 | } |
| 107 | } |
| 108 | return this; |
| 109 | }; |
| 110 | })(window.fossil); |
| 111 |
+11
-2
| --- src/pikchrshow.c | ||
| +++ src/pikchrshow.c | ||
| @@ -207,12 +207,21 @@ | ||
| 207 | 207 | blob_append(pOut, zOut, -1); |
| 208 | 208 | if(PIKCHR_PROCESS_DIV & pikFlags){ |
| 209 | 209 | blob_append(pOut, "</div>\n", 7); |
| 210 | 210 | } |
| 211 | 211 | if(PIKCHR_PROCESS_SRC & pikFlags){ |
| 212 | - blob_appendf(pOut, "<pre class='pikchr-src'>%h</pre>\n", | |
| 213 | - blob_str(&bIn)); | |
| 212 | + static int counter = 0; | |
| 213 | + ++counter; | |
| 214 | + blob_appendf(pOut, "<div class='pikchr-src'>" | |
| 215 | + "<pre id='pikchr-src-%d'>%h</pre>" | |
| 216 | + "<span class='hidden'>" | |
| 217 | + "[<a href='%R/pikchrshow?fromSession' " | |
| 218 | + "class='pikchr-src-pikchrshow' target='_new-%d' " | |
| 219 | + "data-pikchrid='pikchr-src-%d'" | |
| 220 | + ">→ /pikchrshow</a>]</span>" | |
| 221 | + "</div>\n", | |
| 222 | + counter, blob_str(&bIn), counter, counter); | |
| 214 | 223 | } |
| 215 | 224 | if(PIKCHR_PROCESS_DIV & pikFlags){ |
| 216 | 225 | blob_append(pOut, "</div>\n", 7); |
| 217 | 226 | } |
| 218 | 227 | }else{ |
| 219 | 228 |
| --- src/pikchrshow.c | |
| +++ src/pikchrshow.c | |
| @@ -207,12 +207,21 @@ | |
| 207 | blob_append(pOut, zOut, -1); |
| 208 | if(PIKCHR_PROCESS_DIV & pikFlags){ |
| 209 | blob_append(pOut, "</div>\n", 7); |
| 210 | } |
| 211 | if(PIKCHR_PROCESS_SRC & pikFlags){ |
| 212 | blob_appendf(pOut, "<pre class='pikchr-src'>%h</pre>\n", |
| 213 | blob_str(&bIn)); |
| 214 | } |
| 215 | if(PIKCHR_PROCESS_DIV & pikFlags){ |
| 216 | blob_append(pOut, "</div>\n", 7); |
| 217 | } |
| 218 | }else{ |
| 219 |
| --- src/pikchrshow.c | |
| +++ src/pikchrshow.c | |
| @@ -207,12 +207,21 @@ | |
| 207 | blob_append(pOut, zOut, -1); |
| 208 | if(PIKCHR_PROCESS_DIV & pikFlags){ |
| 209 | blob_append(pOut, "</div>\n", 7); |
| 210 | } |
| 211 | if(PIKCHR_PROCESS_SRC & pikFlags){ |
| 212 | static int counter = 0; |
| 213 | ++counter; |
| 214 | blob_appendf(pOut, "<div class='pikchr-src'>" |
| 215 | "<pre id='pikchr-src-%d'>%h</pre>" |
| 216 | "<span class='hidden'>" |
| 217 | "[<a href='%R/pikchrshow?fromSession' " |
| 218 | "class='pikchr-src-pikchrshow' target='_new-%d' " |
| 219 | "data-pikchrid='pikchr-src-%d'" |
| 220 | ">→ /pikchrshow</a>]</span>" |
| 221 | "</div>\n", |
| 222 | counter, blob_str(&bIn), counter, counter); |
| 223 | } |
| 224 | if(PIKCHR_PROCESS_DIV & pikFlags){ |
| 225 | blob_append(pOut, "</div>\n", 7); |
| 226 | } |
| 227 | }else{ |
| 228 |