#267: jump to top and bottom buttons for long pastes and editor #269
@@ -884,3 +884,17 @@ button[type="submit"]:focus-visible,
|
|||||||
.created-banner { display: block; }
|
.created-banner { display: block; }
|
||||||
/* #167: gutter rows for wrapped paste view — one row per visual code line */
|
/* #167: gutter rows for wrapped paste view — one row per visual code line */
|
||||||
.gutline { display: block; }
|
.gutline { display: block; }
|
||||||
|
|
||||||
|
/* #267: jump to top/bottom pills for long pastes and the editor.
|
||||||
|
Hidden unless JS (jump.js) detects content more than 2x the viewport. */
|
||||||
|
.jumpnav {
|
||||||
|
position: fixed;
|
||||||
|
right: 18px;
|
||||||
|
bottom: 18px;
|
||||||
|
z-index: 50;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.jumpnav.hidden { display: none; }
|
||||||
|
.jump-btn { box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25); }
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/* #267: jump to top / bottom controls for long content.
|
||||||
|
Paste view scrolls the window; the /new editor scrolls its textarea.
|
||||||
|
The active scroller is chosen via data-jump-scroll on the script tag. */
|
||||||
|
(function () {
|
||||||
|
var nav = document.getElementById('jumpnav');
|
||||||
|
if (!nav) return;
|
||||||
|
var scroller = window;
|
||||||
|
var sel = nav.dataset.jumpScroll;
|
||||||
|
if (sel) scroller = document.querySelector(sel);
|
||||||
|
|
||||||
|
function el() {
|
||||||
|
return scroller === window ? document.scrollingElement : scroller;
|
||||||
|
}
|
||||||
|
function isLarge() {
|
||||||
|
var e = el();
|
||||||
|
if (!e) return false;
|
||||||
|
var visible = scroller === window ? window.innerHeight : e.clientHeight;
|
||||||
|
return e.scrollHeight > visible * 2;
|
||||||
|
}
|
||||||
|
function refresh() {
|
||||||
|
nav.classList.toggle('hidden', !isLarge());
|
||||||
|
}
|
||||||
|
function jump(toTop) {
|
||||||
|
var e = el();
|
||||||
|
if (!e) return;
|
||||||
|
if (scroller === window) {
|
||||||
|
window.scrollTo({ top: toTop ? 0 : e.scrollHeight });
|
||||||
|
} else {
|
||||||
|
e.scrollTop = toTop ? 0 : e.scrollHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nav.addEventListener('click', function (ev) {
|
||||||
|
var b = ev.target.closest('[data-jump]');
|
||||||
|
if (!b) return;
|
||||||
|
ev.preventDefault();
|
||||||
|
jump(b.dataset.jump === 'top');
|
||||||
|
});
|
||||||
|
window.addEventListener('resize', refresh);
|
||||||
|
if (scroller !== window && scroller) scroller.addEventListener('input', refresh);
|
||||||
|
refresh();
|
||||||
|
})();
|
||||||
@@ -33,6 +33,10 @@
|
|||||||
<div class="spacer spacer-flex"></div>
|
<div class="spacer spacer-flex"></div>
|
||||||
<button class="btn" id="create">Create</button>
|
<button class="btn" id="create">Create</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="jumpnav hidden" id="jumpnav" data-jump-scroll="#content">
|
||||||
|
<button type="button" class="btn jump-btn" data-jump="top">Top</button>
|
||||||
|
<button type="button" class="btn jump-btn" data-jump="bottom">Bottom</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pane-r">
|
<div class="pane-r">
|
||||||
@@ -90,4 +94,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="/static/new.js" defer></script>
|
<script src="/static/new.js" defer></script>
|
||||||
|
<script src="/static/jump.js" defer></script>
|
||||||
{{template "foot" .}}
|
{{template "foot" .}}
|
||||||
|
|||||||
@@ -55,8 +55,13 @@
|
|||||||
<div class="code" id="code"><div class="gutter" id="gutter">{{.Gutter}}</div><div class="codebody" id="codebody">{{.ContentHTML}}</div></div>
|
<div class="code" id="code"><div class="gutter" id="gutter">{{.Gutter}}</div><div class="codebody" id="codebody">{{.ContentHTML}}</div></div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
<div class="jumpnav hidden" id="jumpnav">
|
||||||
|
<button type="button" class="btn jump-btn" data-jump="top">Top</button>
|
||||||
|
<button type="button" class="btn jump-btn" data-jump="bottom">Bottom</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" id="raw-content" value="{{.ContentAttr}}">
|
<input type="hidden" id="raw-content" value="{{.ContentAttr}}">
|
||||||
<script src="/static/paste.js" defer data-paste-id="{{.ID}}"></script>
|
<script src="/static/paste.js" defer data-paste-id="{{.ID}}"></script>
|
||||||
<script src="/static/paste-lines.js" defer></script>
|
<script src="/static/paste-lines.js" defer></script>
|
||||||
|
<script src="/static/jump.js" defer></script>
|
||||||
{{template "foot" .}}
|
{{template "foot" .}}
|
||||||
|
|||||||
Reference in New Issue
Block a user