8276768: Snippet copy feature should use button instead of link
Reviewed-by: prappo
This commit is contained in:
parent
d8b0dee65e
commit
0395e4ef8c
@ -447,13 +447,14 @@ public class TagletWriterImpl extends TagletWriter {
|
||||
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 {
|
||||
div.snippet-container button.snippet-copy:hover {
|
||||
opacity: 100%;
|
||||
}
|
||||
a.snippet-copy:active img {
|
||||
background: #d3d3d3;
|
||||
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 class TestSnippetTag extends JavadocTester {
|
||||
<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 @@ public class TestSnippetTag extends JavadocTester {
|
||||
"""
|
||||
<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 @@ public class TestSnippetTag extends JavadocTester {
|
||||
"""
|
||||
<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 @@ public class TestSnippetTag extends JavadocTester {
|
||||
"""
|
||||
<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 class TestSnippetTag extends JavadocTester {
|
||||
"""
|
||||
<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 class TestSnippetTag extends JavadocTester {
|
||||
"""
|
||||
<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 @@ public class TestSnippetTag extends JavadocTester {
|
||||
"""
|
||||
<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 @@ public class TestSnippetTag extends JavadocTester {
|
||||
"""
|
||||
<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 @@ public class LinkChecker extends HtmlChecker {
|
||||
|
||||
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 @@ public class LinkChecker extends HtmlChecker {
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user