Skip to content
Permalink
Browse files
8276768: Snippet copy feature should use button instead of link
Reviewed-by: prappo
  • Loading branch information
hns committed Nov 8, 2021
1 parent d8b0dee commit 0395e4ef8ced8385cc2c9b3bea4c6f4490c62d2b
Showing 5 changed files with 70 additions and 70 deletions.
@@ -447,13 +447,14 @@ protected Content snippetTagOutput(Element element, SnippetTree tag, StyledText
String copyText = resources.getText("doclet.Copy_snippet_to_clipboard");
String copiedText = resources.getText("doclet.Copied_snippet_to_clipboard");
HtmlTree snippetContainer = HtmlTree.DIV(HtmlStyle.snippetContainer,
HtmlTree.A("#", new HtmlTree(TagName.IMG)
new HtmlTree(TagName.BUTTON)
.add(HtmlTree.SPAN(Text.of(copyText))
.put(HtmlAttr.DATA_COPIED, copiedText))
.add(new HtmlTree(TagName.IMG)
.put(HtmlAttr.SRC, htmlWriter.pathToRoot.resolve(DocPaths.CLIPBOARD_SVG).getPath())
.put(HtmlAttr.ALT, copyText))
.addStyle(HtmlStyle.snippetCopy)
.put(HtmlAttr.ONCLICK, "copySnippet(this)")
.put(HtmlAttr.ARIA_LABEL, copyText)
.put(HtmlAttr.DATA_COPIED, copiedText));
.put(HtmlAttr.ONCLICK, "copySnippet(this)"));
return snippetContainer.add(pre.add(code));
}

@@ -106,19 +106,24 @@ function indexFilesLoaded() {
&& tagSearchIndex;
}

function copySnippet(link) {
function copySnippet(button) {
var textarea = document.createElement("textarea");
textarea.style.height = 0;
document.body.appendChild(textarea);
textarea.value = link.nextElementSibling.innerText;
textarea.value = button.nextElementSibling.innerText;
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
link.classList.add("copied");
var parent = link.parentElement;
parent.onmouseleave = parent.ontouchend = function() {
link.classList.remove("copied");
};
var span = button.firstElementChild;
var copied = span.getAttribute("data-copied");
if (span.innerHTML !== copied) {
var initialLabel = span.innerHTML;
span.innerHTML = copied;
var parent = button.parentElement;
parent.onmouseleave = parent.ontouchend = function() {
span.innerHTML = initialLabel;
};
}
}

// Workaround for scroll position not being included in browser history (8249133)
@@ -936,62 +936,56 @@ pre.snippet {
div.snippet-container {
position: relative;
}
a.snippet-copy {
button.snippet-copy {
position: absolute;
top: 8px;
right: 8px;
top: 6px;
right: 6px;
height: 1.7em;
opacity: 50%;
transition: opacity 0.2s;
padding: 2px;
border: none;
cursor: pointer;
background: none;
}
a.snippet-copy img {
button.snippet-copy img {
width: 18px;
height: 18px;
padding: 0.05em 0;
opacity: 50%;
transition: opacity 0.2s;
background: none;
}
div.snippet-container:hover a.snippet-copy img {
div.snippet-container:hover button.snippet-copy {
opacity: 80%;
}
div.snippet-container a.snippet-copy:hover img {
opacity: 100%;
}
a.snippet-copy:active img {
background: #d3d3d3;
div.snippet-container button.snippet-copy:hover {
opacity: 100%;
}
a.snippet-copy::before {
button.snippet-copy span {
color: #3d3d3d;
content: attr(aria-label);
font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;
font-size: 85%;
line-height: 1.2em;
padding: 0.2em;
position: absolute;
opacity: 80%;
transition: opacity 0.2s;
position: relative;
white-space: nowrap;
top: -0.01em;
right: 1.5em;
top: -0.5em;
display: none;
}
div.snippet-container:hover a.snippet-copy::before {
display: inherit;
div.snippet-container:hover button.snippet-copy span {
display: inline;
}
div.snippet-container a.snippet-copy:hover::before {
button.snippet-copy:active {
background: #d3d3d3;
opacity: 100%;
}
a.snippet-copy.copied::before {
content: attr(data-copied);
}
a.snippet-copy:active::before {
background-color: #dadada;
}
@media screen and (max-width: 800px) {
pre.snippet {
padding-top: 26px;
}
a.snippet-copy {
top: 6px;
right: 6px;
button.snippet-copy {
top: 4px;
right: 4px;
}
}
pre.snippet .italic {
@@ -224,9 +224,9 @@ public String langAttribute() {
<span class="element-name">case%s</span>()</div>
<div class="block">A method.
\s
<div class="snippet-container"><a href="#" class="snippet-copy" onclick="cop\
ySnippet(this)" aria-label="Copy" data-copied="Copied!"><img src="../copy.sv\
g" alt="Copy"></a>
<div class="snippet-container"><button class="snippet-copy" onclick="copySni\
ppet(this)"><span data-copied="Copied!">Copy</span><img src="../copy.svg" al\
t="Copy"></button>
<pre class="snippet"%s><code%s> Hello, Snippet!
</code></pre>
</div>
@@ -948,9 +948,9 @@ record TestCase(String input, String expectedOutput) { }
"""
<span class="element-name">case%s</span>()</div>
<div class="block">
<div class="snippet-container"><a href="#" class="snippet-copy" onclick="cop\
ySnippet(this)" aria-label="Copy" data-copied="Copied!"><img src="../copy.sv\
g" alt="Copy"></a>
<div class="snippet-container"><button class="snippet-copy" onclick="copySni\
ppet(this)"><span data-copied="Copied!">Copy</span><img src="../copy.svg" al\
t="Copy"></button>
<pre class="snippet"><code>%s</code></pre>
</div>""".formatted(id, t.expectedOutput()));
});
@@ -1044,9 +1044,9 @@ record TestCase(String input, Function<String, String> expectedTransformation) {
"""
<span class="element-name">case%s</span>()</div>
<div class="block">
<div class="snippet-container"><a href="#" class="snippet-copy" onclick="cop\
ySnippet(this)" aria-label="Copy" data-copied="Copied!"><img src="../copy.sv\
g" alt="Copy"></a>
<div class="snippet-container"><button class="snippet-copy" onclick="copySni\
ppet(this)"><span data-copied="Copied!">Copy</span><img src="../copy.svg" al\
t="Copy"></button>
<pre class="snippet"><code>%s</code></pre>
</div>""".formatted(index, expectedOutput));
});
@@ -1605,9 +1605,9 @@ record TestCase(Snippet snippet, String expectedOutput) { }
"""
<span class="element-name">case%s</span>()</div>
<div class="block">
<div class="snippet-container"><a href="#" class="snippet-copy" onclick="cop\
ySnippet(this)" aria-label="Copy" data-copied="Copied!"><img src="../copy.sv\
g" alt="Copy"></a>
<div class="snippet-container"><button class="snippet-copy" onclick="copySni\
ppet(this)"><span data-copied="Copied!">Copy</span><img src="../copy.svg" al\
t="Copy"></button>
<pre class="snippet"><code>%s</code></pre>
</div>""".formatted(index, t.expectedOutput()));
});
@@ -1722,18 +1722,18 @@ public void testAttributeValueSyntaxCurly(Path base) throws Exception {
"""
<span class="element-name">case0</span>()</div>
<div class="block">
<div class="snippet-container"><a href="#" class="snippet-copy" onclick="copySni\
ppet(this)" aria-label="Copy" data-copied="Copied!"><img src="../copy.svg" alt="\
Copy"></a>
<div class="snippet-container"><button class="snippet-copy" onclick="copySnippet\
(this)"><span data-copied="Copied!">Copy</span><img src="../copy.svg" alt="Copy"\
></button>
<pre class="snippet"><code></code></pre>
</div>""");
checkOutput("pkg/A.html", true,
"""
<span class="element-name">case1</span>()</div>
<div class="block">
<div class="snippet-container"><a href="#" class="snippet-copy" onclick="copySni\
ppet(this)" aria-label="Copy" data-copied="Copied!"><img src="../copy.svg" alt="\
Copy"></a>
<div class="snippet-container"><button class="snippet-copy" onclick="copySnippet\
(this)"><span data-copied="Copied!">Copy</span><img src="../copy.svg" alt="Copy"\
></button>
<pre class="snippet"><code></code></pre>
</div>""");
}
@@ -1832,9 +1832,9 @@ public void testAttributeValueSyntax(Path base) throws Exception {
"""
<span class="element-name">case%s</span>()</div>
<div class="block">
<div class="snippet-container"><a href="#" class="snippet-copy" onclick="cop\
ySnippet(this)" aria-label="Copy" data-copied="Copied!"><img src="../copy.sv\
g" alt="Copy"></a>
<div class="snippet-container"><button class="snippet-copy" onclick="copySni\
ppet(this)"><span data-copied="Copied!">Copy</span><img src="../copy.svg" al\
t="Copy"></button>
<pre class="snippet"><code>2</code></pre>
</div>
""".formatted(j));
@@ -1916,9 +1916,9 @@ record TestCase(Snippet snippet, String expectedOutput) { }
"""
<span class="element-name">case%s</span>()</div>
<div class="block">
<div class="snippet-container"><a href="#" class="snippet-copy" onclick="cop\
ySnippet(this)" aria-label="Copy" data-copied="Copied!"><img src="../copy.sv\
g" alt="Copy"></a>
<div class="snippet-container"><button class="snippet-copy" onclick="copySni\
ppet(this)"><span data-copied="Copied!">Copy</span><img src="../copy.svg" al\
t="Copy"></button>
<pre class="snippet"><code>%s</code></pre>
</div>""".formatted(index, t.expectedOutput()));
});
@@ -2248,9 +2248,9 @@ record TestCase(Snippet snippet, String expectedOutput) { }
"""
<span class="element-name">case%s</span>()</div>
<div class="block">
<div class="snippet-container"><a href="#" class="snippet-copy" onclick="cop\
ySnippet(this)" aria-label="Copy" data-copied="Copied!"><img src="../copy.sv\
g" alt="Copy"></a>
<div class="snippet-container"><button class="snippet-copy" onclick="copySni\
ppet(this)"><span data-copied="Copied!">Copy</span><img src="../copy.svg" al\
t="Copy"></button>
<pre class="snippet"><code>%s</code></pre>
</div>""".formatted(index, t.expectedOutput()));
});
@@ -351,7 +351,7 @@ void addID(int line, String name) {

void addReference(String name, Path from, int line) {
if (checked) {
if (name != null && !name.isEmpty()) {
if (name != null) {
ID id = map.get(name);
if (id == null || !id.declared) {
error(from, line, "id not found: " + this.name + "#" + name);
@@ -368,7 +368,7 @@ void addReference(String name, Path from, int line) {

void check() {
map.forEach((name, id) -> {
if (name != null && !name.isEmpty() && !id.declared) {
if (name != null && !id.declared) {
//log.error(currFile, 0, "id not declared: " + name);
for (Position ref : id.references) {
error(ref.path, ref.line, "id not found: " + this.name + "#" + name);

1 comment on commit 0395e4e

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 0395e4e Nov 8, 2021

Choose a reason for hiding this comment

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

Please sign in to comment.