From e4c23697dae5a27ec992608f0778ed7ac47a41e1 Mon Sep 17 00:00:00 2001 From: Florian Zschocke Date: Mon, 21 Nov 2022 01:11:52 +0100 Subject: Add a "Copied" tooltip to the copy-to-clipboard button This is not the ideal version, since the height is too low for the tooltip used for the drop-down menus. Probably has something to do with the container or something. But at least something is there now, even if not the most beautiful. --- .../com/gitblit/wicket/pages/RepositoryPage.java | 5 + .../java/com/gitblit/wicket/pages/SummaryPage.html | 7 - .../gitblit/wicket/panels/RepositoryUrlPanel.html | 10 +- src/main/resources/clipboard/gitblit-ctcbtn.js | 74 +++++++++ src/main/resources/gitblit.css | 172 ++++++++++++++++++++- 5 files changed, 256 insertions(+), 12 deletions(-) create mode 100644 src/main/resources/clipboard/gitblit-ctcbtn.js diff --git a/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java b/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java index 4d30e049..b30aee97 100644 --- a/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java +++ b/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java @@ -171,6 +171,11 @@ public abstract class RepositoryPage extends RootPage { add(searchForm); searchForm.setTranslatedAttributes(); + // load clipboard library to copy repository URL + addBottomScript("../../clipboard/clipboard.min.js"); + // instantiate clipboard + addBottomScript("../../clipboard/gitblit-ctcbtn.js"); + // set stateless page preference setStatelessHint(true); } diff --git a/src/main/java/com/gitblit/wicket/pages/SummaryPage.html b/src/main/java/com/gitblit/wicket/pages/SummaryPage.html index b6afc301..8915ecf5 100644 --- a/src/main/java/com/gitblit/wicket/pages/SummaryPage.html +++ b/src/main/java/com/gitblit/wicket/pages/SummaryPage.html @@ -62,13 +62,6 @@ - - - - - \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.html b/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.html index 1cadd7d5..e4b7427a 100644 --- a/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.html +++ b/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.html @@ -12,12 +12,14 @@
-
+
[repository primary url] - + + +
[repository primary url permission]
@@ -33,7 +35,7 @@
-
+
@@ -87,7 +89,7 @@ - + diff --git a/src/main/resources/clipboard/gitblit-ctcbtn.js b/src/main/resources/clipboard/gitblit-ctcbtn.js new file mode 100644 index 00000000..ddb2ddad --- /dev/null +++ b/src/main/resources/clipboard/gitblit-ctcbtn.js @@ -0,0 +1,74 @@ +// Instantiate the clipboarding +var clipboard = new ClipboardJS('.ctcbtn'); + +clipboard.on('success', function (e) { + showTooltip(e.trigger, "Copied!"); +}); + +clipboard.on('error', function (e) { + showTooltip(e.trigger, fallbackMessage(e.action)); +}); + +// Attach events to buttons to clear tooltip again +var btns = document.querySelectorAll('.ctcbtn'); +for (var i = 0; i < btns.length; i++) { + btns[i].addEventListener('mouseleave', clearTooltip); + btns[i].addEventListener('blur', clearTooltip); +} + + +function findTooltipped(elem) { + do { + if (elem.classList.contains('tooltipped')) return elem; + elem = elem.parentElement; + } while (elem != null); + return null; +} + +// Show or hide tooltip by setting the tooltipped-active class +// on a parent that contains tooltipped. Since the copy button +// could be and image, or be hidden after clicking, the tooltipped +// element might be higher in the hierarchy. +var ttset; +function showTooltip(elem, msg) { + let ttelem = findTooltipped(elem); + if (ttelem != null) { + ttelem.classList.add('tooltipped-active'); + ttelem.setAttribute('data-tt-text', msg); + ttset=Date.now(); + } + else { + console.warn("Could not find any tooltipped element for clipboard button.", elem); + } +} + +function clearTooltip(e) { + let ttelem = findTooltipped(e.currentTarget); + if (ttelem != null) { + let now = Date.now(); + if (now - ttset < 500) { + // Give the tooltip some time to display + setTimeout(function(){ttelem.classList.remove('tooltipped-active')}, 1000) + } + else { + ttelem.classList.remove('tooltipped-active'); + } + } + else { + console.warn("Could not find any tooltipped element for clipboard button.", e.currentTarget); + } +} + +// If the API is not supported, at least fall back to a message saying +// that now that the text is selected, Ctrl-C can be used. +// This is still a problem in the repo URL dropdown. When it is hidden, Ctrl-C doesn't work. +function fallbackMessage(action) { + var actionMsg = ""; + if (/Mac/i.test(navigator.userAgent)) { + actionMsg = "Press ⌘-C to copy"; + } + else { + actionMsg = "Press Ctrl-C to copy"; + } + return actionMsg; +} diff --git a/src/main/resources/gitblit.css b/src/main/resources/gitblit.css index f7271788..bd2befd3 100644 --- a/src/main/resources/gitblit.css +++ b/src/main/resources/gitblit.css @@ -2408,4 +2408,174 @@ table.filestore-status { font-weight: 200; font-size: 1em; font-variant: normal; -} \ No newline at end of file +} + + +/* + Copy-to-clipboard tooltip styling from Github's primer.css + https://primer.style/css/components/tooltips + Adjusted to not hover but fade-in/out on clipboard events. +*/ + +.tooltipped { + position:relative +} + +.tooltipped:after { + position: absolute; + z-index: 1000000; + padding: 5px 8px; + + font: normal normal 11px/1.5 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; + color: #fff; + background: rgba(42, 42, 42, .8); + text-align: center; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-wrap: break-word; + white-space: pre; + pointer-events: none; + content: attr(data-tt-text); + border-radius: 3px; + -webkit-font-smoothing:subpixel-antialiased; + + opacity: 0; + transition: 0.5s opacity; +} + +.tooltipped:before { + position: absolute; + z-index: 1000001; + + width: 0; + height: 0; + color: rgba(42, 42, 42, .8); + pointer-events: none; + content: ""; + border:5px solid transparent; + + opacity: 0; + transition: 0.5s opacity; +} + +.tooltipped-active:before, .tooltipped-active:after { + opacity: 1; + text-decoration:none +} + +.tooltipped-s:after, .tooltipped-se:after, .tooltipped-sw:after { + top: 100%; + right: 50%; + margin-top:5px +} + +.tooltipped-s:before, .tooltipped-se:before, .tooltipped-sw:before { + top: auto; + right: 50%; + bottom: -5px; + margin-right: -5px; + border-bottom-color:rgba(42, 42, 42, .8) +} + +.tooltipped-se:after { + right: auto; + left: 50%; + margin-left:-15px +} + +.tooltipped-sw:after { + margin-right:-15px +} + +.tooltipped-n:after, .tooltipped-ne:after, .tooltipped-nw:after { + right: 50%; + bottom: 100%; + margin-bottom:5px +} + +.tooltipped-n:before, .tooltipped-ne:before, .tooltipped-nw:before { + top: -5px; + right: 50%; + bottom: auto; + margin-right: -5px; + border-top-color:rgba(42, 42, 42, .8) +} + +.tooltipped-ne:after { + right: auto; + left: 50%; + margin-left:-15px +} + +.tooltipped-nw:after { + margin-right:-15px +} + +.tooltipped-s:after, .tooltipped-n:after { + -webkit-transform: translateX(50%); + -ms-transform: translateX(50%); + transform:translateX(50%) +} + +.tooltipped-w:after { + right: 100%; + bottom: 50%; + margin-right: 5px; + -webkit-transform: translateY(50%); + -ms-transform: translateY(50%); + transform:translateY(50%) +} + +.tooltipped-w:before { + top: 50%; + bottom: 50%; + left: -5px; + margin-top: -5px; + border-left-color:rgba(42, 42, 42, .8) +} + +.tooltipped-e:after { + bottom: 50%; + left: 100%; + margin-left: 5px; + -webkit-transform: translateY(50%); + -ms-transform: translateY(50%); + transform:translateY(50%) +} + +.tooltipped-e:before { + top: 50%; + right: -5px; + bottom: 50%; + margin-top: -5px; + border-right-color:rgba(42, 42, 42, .8) +} + + +.tooltipped-sticky:before, .tooltipped-sticky:after { + display:inline-block +} + + +.fullscreen-overlay-enabled.dark-theme .tooltipped:after { + color: #000; + background:rgba(200, 200, 200, .8) +} + +.fullscreen-overlay-enabled.dark-theme .tooltipped .tooltipped-s:before, .fullscreen-overlay-enabled.dark-theme .tooltipped .tooltipped-se:before, .fullscreen-overlay-enabled.dark-theme .tooltipped .tooltipped-sw:before { + border-bottom-color:rgba(200, 200, 200, .8) +} + +.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-n:before, .fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-ne:before, .fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-nw:before { + border-top-color:rgba(200, 200, 200, .8) +} + +.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-e:before { + border-right-color:rgba(200, 200, 200, .8) +} + +.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-w:before { + border-left-color:rgba(200, 200, 200, .8) +} -- cgit v1.2.3