Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions app/assets/javascripts/codeblocks.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
$(() => {
$(".post--content pre > code")
const buttonTemplate = `<button class="copy-button button is-muted is-outlined has-margin-2">Copy</button>`;

$('.post--content pre > code')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: would this be a good opportunity to phase out jQuery for this file?

.parent()
.each(function() {
const content = $(this).text()
.each(function () {
const $button = $(buttonTemplate);
const $content = $(this).text();
const numLines = $content.trim().split(/\r?\n/).length

if (numLines <= 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using <= 1 suggests we are considering not only the case where numLines is 1, but also the case where numLines is 0. Should that case avoid having the Copy button (of either size)?

This seems a very rare case. The only example I can think of where avoiding having the Copy button might be a problem is Code Golf. In the esolang (esoteric programming language) Whitespace it's possible to have a valid program composed entirely of newlines, tabs, and spaces, which would all be removed by the .trim() leaving zero length, but still needing a Copy button.

If we wanted to cover both of these rare cases we could also test the length of the content:

  • For zero length content, show no button.
  • For zero lines after trimming, but non-zero length content, show the small or large Copy button depending on number of newlines.

Is there a simpler approach where we find the height of the code block without trimming? Since both \r\n and \n contain one \n, could we just count how many times \n occurs in the content to determine the number of lines, and choose a button accordingly:

  • 0 lines: No button
  • 1 line: Small button
  • Anything else: Large button

Maybe something like (untested):

numLines = $content.length == 0 ? 0 : $content.match(/\n/g).length + 1

$button.addClass('is-small');
}

$(this)
.wrap('<div style="position:relative;"></div>')
.parent()
.prepend($('<button class="copy-button button is-muted is-outlined has-margin-2">Copy</button>')
.click(function () {
navigator.clipboard.writeText(content);
.prepend(
$button.click(function () {
navigator.clipboard.writeText($content);
$(this).text('Copied!');
setTimeout(() => { $(this).text('Copy'); }, 2000);
}))
});
});
setTimeout(() => {
$(this).text('Copy');
}, 2000);
}),
);
});
});

4 changes: 4 additions & 0 deletions app/assets/stylesheets/utilities.scss
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ pre.pre-wrap {
display: none;
position: absolute;
right: 0;

&.is-small {
top: -1px;
}
}

div:hover > .copy-button {
Expand Down