8299718: JavaDoc: Buttons to copy specific documentation URL are not accessible
Reviewed-by: jjg
This commit is contained in:
parent
4de24cdbe6
commit
094e03de6a
@ -89,8 +89,9 @@ public class SearchWriter extends HtmlDocletWriter {
|
||||
*/
|
||||
protected void addSearchFileContents(Content contentTree) {
|
||||
|
||||
String copyText = resources.getText("doclet.Copy_url_to_clipboard");
|
||||
String copiedText = resources.getText("doclet.Copied_url_to_clipboard");
|
||||
String copyText = resources.getText("doclet.Copy_to_clipboard");
|
||||
String copiedText = resources.getText("doclet.Copied_to_clipboard");
|
||||
String copyUrlText = resources.getText("doclet.Copy_url_to_clipboard");
|
||||
Content helpSection = Text.EMPTY;
|
||||
// Suppress link to help page if no help page is generated or a custom help page is used.
|
||||
HtmlOptions options = configuration.getOptions();
|
||||
@ -117,10 +118,11 @@ public class SearchWriter extends HtmlDocletWriter {
|
||||
.add(new HtmlTree(TagName.BUTTON)
|
||||
.add(new HtmlTree(TagName.IMG)
|
||||
.put(HtmlAttr.SRC, pathToRoot.resolve(DocPaths.CLIPBOARD_SVG).getPath())
|
||||
.put(HtmlAttr.ALT, copyText))
|
||||
.put(HtmlAttr.ALT, copyUrlText))
|
||||
.add(HtmlTree.SPAN(Text.of(copyText))
|
||||
.put(HtmlAttr.DATA_COPIED, copiedText))
|
||||
.addStyle(HtmlStyle.copy)
|
||||
.put(HtmlAttr.ARIA_LABEL, copyUrlText)
|
||||
.setId(HtmlId.of("page-search-copy")))
|
||||
.add(HtmlTree.P(HtmlTree.INPUT("checkbox", HtmlId.of("search-redirect")))
|
||||
.add(HtmlTree.LABEL("search-redirect",
|
||||
|
@ -711,17 +711,19 @@ public class TagletWriterImpl extends TagletWriter {
|
||||
code.add(c);
|
||||
}
|
||||
});
|
||||
String copyText = resources.getText("doclet.Copy_snippet_to_clipboard");
|
||||
String copiedText = resources.getText("doclet.Copied_snippet_to_clipboard");
|
||||
String copyText = resources.getText("doclet.Copy_to_clipboard");
|
||||
String copiedText = resources.getText("doclet.Copied_to_clipboard");
|
||||
String copySnippetText = resources.getText("doclet.Copy_snippet_to_clipboard");
|
||||
var snippetContainer = HtmlTree.DIV(HtmlStyle.snippetContainer,
|
||||
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))
|
||||
.put(HtmlAttr.ALT, copySnippetText))
|
||||
.addStyle(HtmlStyle.copy)
|
||||
.addStyle(HtmlStyle.snippetCopy)
|
||||
.put(HtmlAttr.ARIA_LABEL, copySnippetText)
|
||||
.put(HtmlAttr.ONCLICK, "copySnippet(this)"));
|
||||
return snippetContainer.add(pre.add(code));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -39,23 +39,8 @@ $(function() {
|
||||
copy[0].onmouseenter();
|
||||
}
|
||||
function copyLink(e) {
|
||||
var textarea = document.createElement("textarea");
|
||||
textarea.style.height = 0;
|
||||
document.body.appendChild(textarea);
|
||||
textarea.value = this.previousSibling.innerText;
|
||||
textarea.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(textarea);
|
||||
var span = this.lastElementChild;
|
||||
var copied = span.getAttribute("data-copied");
|
||||
if (span.innerHTML !== copied) {
|
||||
var initialLabel = span.innerHTML;
|
||||
span.innerHTML = copied;
|
||||
var parent = this.parentElement.parentElement;
|
||||
parent.onmouseleave = parent.ontouchend = copy[0].onmouseenter = function() {
|
||||
span.innerHTML = initialLabel;
|
||||
};
|
||||
}
|
||||
copyToClipboard(this.previousSibling.innerText);
|
||||
switchCopyLabel(this, this.lastElementChild);
|
||||
}
|
||||
copy.click(copyLink);
|
||||
copy[0].onmouseenter = function() {};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,8 +31,9 @@ const messages = {
|
||||
loading: "##REPLACE:doclet.search.loading##",
|
||||
searching: "##REPLACE:doclet.search.searching##",
|
||||
redirecting: "##REPLACE:doclet.search.redirecting##",
|
||||
copyUrl: "##REPLACE:doclet.Copy_url_to_clipboard##",
|
||||
urlCopied: "##REPLACE:doclet.Copied_url_to_clipboard##"
|
||||
copyToClipboard: "##REPLACE:doclet.Copy_to_clipboard##",
|
||||
copyUrlToClipboard: "##REPLACE:doclet.Copy_url_to_clipboard##",
|
||||
copiedToClipboard: "##REPLACE:doclet.Copied_to_clipboard##"
|
||||
}
|
||||
const categories = {
|
||||
modules: "##REPLACE:doclet.search.modules##",
|
||||
@ -407,16 +408,17 @@ $(function() {
|
||||
$("ul.sub-nav-list-small li a").click(collapse);
|
||||
$("input#search-input").focus(collapse);
|
||||
$("main").click(collapse);
|
||||
$("section[id] > :header, :header[id], :header:has(a[id])").hover(
|
||||
function () {
|
||||
$(this).append($("<button class='copy copy-header' onclick='copyUrl(this)'> " +
|
||||
"<img src='" + pathtoroot + "copy.svg' alt='" + messages.copyUrl + "'> " +
|
||||
"<span data-copied='" + messages.urlCopied + "'></span></button>"));
|
||||
},
|
||||
function () {
|
||||
$(this).find("button:last").remove();
|
||||
$("section[id] > :header, :header[id], :header:has(a[id])").each(function(idx, el) {
|
||||
// Create copy-to-clipboard buttons for headers with an associated id attribute
|
||||
var hdr = $(el);
|
||||
var id = hdr.attr("id") || hdr.parent("section").attr("id") || hdr.children("a").attr("id");
|
||||
if (id) {
|
||||
hdr.append($("<button class='copy copy-header' onclick='copyUrl(this)' aria-label='"
|
||||
+ messages.copyUrlToClipboard +"'> " + "<img src='" + pathtoroot + "copy.svg' alt='" +
|
||||
messages.copyUrlToClipboard + "'> " + "<span data-copied='" + messages.copiedToClipboard +
|
||||
"'>" + messages.copyToClipboard + "</span></button>"));
|
||||
}
|
||||
);
|
||||
});
|
||||
$(window).on("orientationchange", collapse).on("resize", function(e) {
|
||||
if (expanded && windowWidth !== window.innerWidth) collapse();
|
||||
});
|
||||
|
@ -55,10 +55,10 @@ doclet.File_not_found=File not found: {0}
|
||||
doclet.snippet_file_not_found=file not found on source path or snippet path: {0}
|
||||
doclet.Copy_Overwrite_warning=File {0} not copied to {1} due to existing file with same name...
|
||||
doclet.Copy_Ignored_warning=File {0} not copied: invalid name
|
||||
doclet.Copy_to_clipboard=Copy
|
||||
doclet.Copied_to_clipboard=Copied!
|
||||
doclet.Copy_url_to_clipboard=Copy URL
|
||||
doclet.Copied_url_to_clipboard=Copied!
|
||||
doclet.Copy_snippet_to_clipboard=Copy
|
||||
doclet.Copied_snippet_to_clipboard=Copied!
|
||||
doclet.Copy_snippet_to_clipboard=Copy snippet
|
||||
doclet.Copying_File_0_To_Dir_1=Copying file {0} to directory {1}...
|
||||
doclet.Copying_File_0_To_File_1=Copying file {0} to file {1}...
|
||||
doclet.No_Public_Classes_To_Document=No public or protected classes found to document.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -202,7 +202,7 @@ function indexFilesLoaded() {
|
||||
// Copy the contents of the local snippet to the clipboard
|
||||
function copySnippet(button) {
|
||||
copyToClipboard(button.nextElementSibling.innerText);
|
||||
switchCopyLabel(button.firstElementChild, button.parentElement);
|
||||
switchCopyLabel(button, button.firstElementChild);
|
||||
}
|
||||
// Copy the link to the adjacent header to the clipboard
|
||||
function copyUrl(button) {
|
||||
@ -221,7 +221,7 @@ function copyUrl(button) {
|
||||
url = url.substring(0, url.indexOf("#"));
|
||||
}
|
||||
copyToClipboard(url + "#" + id);
|
||||
switchCopyLabel(button.lastElementChild, button.parentElement);
|
||||
switchCopyLabel(button, button.lastElementChild);
|
||||
}
|
||||
function copyToClipboard(content) {
|
||||
var textarea = document.createElement("textarea");
|
||||
@ -232,15 +232,19 @@ function copyToClipboard(content) {
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
function switchCopyLabel(span, parent) {
|
||||
function switchCopyLabel(button, span) {
|
||||
var copied = span.getAttribute("data-copied");
|
||||
if (span.innerHTML !== copied) {
|
||||
var initialLabel = span.innerHTML;
|
||||
span.innerHTML = copied;
|
||||
parent.onmouseleave = parent.ontouchend = function() {
|
||||
span.innerHTML = initialLabel;
|
||||
};
|
||||
}
|
||||
button.classList.add("visible");
|
||||
var initialLabel = span.innerHTML;
|
||||
span.innerHTML = copied;
|
||||
setTimeout(function() {
|
||||
button.classList.remove("visible");
|
||||
setTimeout(function() {
|
||||
if (initialLabel !== copied) {
|
||||
span.innerHTML = initialLabel;
|
||||
}
|
||||
}, 100);
|
||||
}, 1900);
|
||||
}
|
||||
// Workaround for scroll position not being included in browser history (8249133)
|
||||
document.addEventListener("DOMContentLoaded", function(e) {
|
||||
|
@ -915,16 +915,21 @@ main a[href*="://"]:focus::after {
|
||||
* Styles for copy-to-clipboard buttons
|
||||
*/
|
||||
button.copy {
|
||||
opacity: 80%;
|
||||
opacity: 70%;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
background:none;
|
||||
transition: opacity 0.2s;
|
||||
transition: opacity 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
:hover > button.copy {
|
||||
opacity: 80%;
|
||||
}
|
||||
button.copy:hover,
|
||||
button.copy:active {
|
||||
button.copy:active,
|
||||
button.copy:focus-visible,
|
||||
button.copy.visible {
|
||||
opacity: 100%;
|
||||
}
|
||||
button.copy img {
|
||||
@ -942,12 +947,19 @@ button.copy span {
|
||||
transition: all 0.1s;
|
||||
font-size: 0.76rem;
|
||||
line-height: 1.2em;
|
||||
opacity: 0;
|
||||
}
|
||||
button.copy:hover span,
|
||||
button.copy:focus-visible span,
|
||||
button.copy.visible span {
|
||||
opacity: 100%;
|
||||
}
|
||||
/* header/section copy button */
|
||||
button.copy-header {
|
||||
margin: 0 0.2em;
|
||||
padding: 0 4px;
|
||||
height: 1.16em;
|
||||
opacity: 0;
|
||||
}
|
||||
button.copy-header img {
|
||||
height: 0.88em;
|
||||
@ -967,15 +979,12 @@ button#page-search-copy img {
|
||||
}
|
||||
button#page-search-copy span {
|
||||
color: var(--body-text-color);
|
||||
content: attr(aria-label);
|
||||
line-height: 1.2em;
|
||||
padding: 0.2em;
|
||||
top: -0.18em;
|
||||
opacity: 0;
|
||||
}
|
||||
div.page-search-info:hover button#page-search-copy,
|
||||
div.page-search-info:hover button#page-search-copy span {
|
||||
opacity: 90%;
|
||||
opacity: 100%;
|
||||
}
|
||||
/* snippet copy button */
|
||||
button.snippet-copy {
|
||||
@ -983,7 +992,6 @@ button.snippet-copy {
|
||||
top: 6px;
|
||||
right: 6px;
|
||||
height: 1.7em;
|
||||
opacity: 50%;
|
||||
padding: 2px;
|
||||
}
|
||||
button.snippet-copy img {
|
||||
@ -992,20 +1000,12 @@ button.snippet-copy img {
|
||||
padding: 0.05em 0;
|
||||
}
|
||||
button.snippet-copy span {
|
||||
content: attr(aria-label);
|
||||
line-height: 1.2em;
|
||||
padding: 0.2em;
|
||||
position: relative;
|
||||
top: -0.5em;
|
||||
display: none;
|
||||
}
|
||||
div.snippet-container:hover button.snippet-copy span {
|
||||
display: inline;
|
||||
}
|
||||
div.snippet-container:hover button.snippet-copy {
|
||||
opacity: 80%;
|
||||
}
|
||||
div.snippet-container button.snippet-copy:hover {
|
||||
opacity: 100%;
|
||||
}
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -129,7 +129,7 @@ public class CheckStylesheetClasses {
|
||||
// or if they are unused and therefore candidates to be deleted.
|
||||
|
||||
// false positives: file extensions and URL components
|
||||
removeAll(styleSheetNames, "css", "png", "w3");
|
||||
removeAll(styleSheetNames, "css", "png", "w3", "org");
|
||||
|
||||
// for doc-comment authors; maybe worthy of inclusion in HtmlStyle, just to be documented
|
||||
removeAll(styleSheetNames, "borderless", "plain", "striped");
|
||||
@ -138,7 +138,8 @@ public class CheckStylesheetClasses {
|
||||
removeAll(styleSheetNames, "result-highlight", "result-item", "copy-header",
|
||||
"search-tag-desc-result", "search-tag-holder-result", "page-search-header",
|
||||
"ui-autocomplete", "ui-autocomplete-category", "ui-state-active", "expanded",
|
||||
"search-result-link", "two-column-search-results", "ui-static-link");
|
||||
"search-result-link", "two-column-search-results", "ui-static-link",
|
||||
"sort-asc", "sort-desc", "visible");
|
||||
|
||||
// very JDK specific
|
||||
styleSheetNames.remove("module-graph");
|
||||
@ -203,7 +204,7 @@ public class CheckStylesheetClasses {
|
||||
throw new AssertionError("Cannot find or access resource " + resource);
|
||||
}
|
||||
String s = new String(in.readAllBytes());
|
||||
Pattern p = Pattern.compile("(?i)(\\s|([a-z][a-z0-9-]*))\\.(?<name>[a-z][a-z0-9-]+)\\b");
|
||||
Pattern p = Pattern.compile("(?i)\\.(?<name>[a-z][a-z0-9-]+)\\b");
|
||||
Matcher m = p.matcher(s);
|
||||
while (m.find()) {
|
||||
names.add(m.group("name"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -119,8 +119,9 @@ public class SnippetTester extends JavadocTester {
|
||||
var idString = id.isEmpty() ? "" : " id=\"%s\"".formatted(id.get());
|
||||
var langString = lang.isEmpty() ? "" : " class=\"language-%s\"".formatted(lang.get());
|
||||
return """
|
||||
<div class="snippet-container"><button class="copy snippet-copy" onclick="copySnippet(this)">\
|
||||
<span data-copied="Copied!">Copy</span><img src="%s" alt="Copy"></button>
|
||||
<div class="snippet-container"><button class="copy snippet-copy" aria-label="Copy snippet" \
|
||||
onclick="copySnippet(this)"><span data-copied="Copied!">Copy</span><img src="%s" alt="Copy \
|
||||
snippet"></button>
|
||||
<pre class="snippet"%s><code%s>%s</code></pre>
|
||||
</div>""".formatted(svgString, idString, langString, content);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -37,6 +37,7 @@ import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class TestSnippetUnnamedPackage extends SnippetTester {
|
||||
|
||||
@ -87,11 +88,9 @@ public class TestSnippetUnnamedPackage extends SnippetTester {
|
||||
"""
|
||||
Before.
|
||||
\s
|
||||
<div class="snippet-container"><button class="copy snippet-copy" onclick="copySnippet\
|
||||
(this)"><span data-copied="Copied!">Copy</span><img src="copy.svg" alt="Copy"></button>
|
||||
<pre class="snippet"><code class="language-java">public class S { }</code></pre>
|
||||
</div>
|
||||
%s
|
||||
|
||||
After.""");
|
||||
After.""".formatted(getSnippetHtmlRepresentation("C.html",
|
||||
"public class S { }", Optional.of("java"))));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user