Rollup merge of #85833 - willcrichton:example-analyzer, r=jyn514
Scrape code examples from examples/ directory for Rustdoc Adds support for the functionality described in https://github.com/rust-lang/rfcs/pull/3123 Matching changes to Cargo are here: https://github.com/rust-lang/cargo/pull/9525 Live demo here: https://willcrichton.net/example-analyzer/warp/trait.Filter.html#method.and
This commit is contained in:
commit
dcf9242795
38 changed files with 1104 additions and 30 deletions
|
|
@ -467,6 +467,11 @@ nav.sub {
|
|||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.rustdoc:not(.source) .example-wrap > pre.line-numbers {
|
||||
width: auto;
|
||||
overflow-x: visible;
|
||||
}
|
||||
|
||||
.rustdoc .example-wrap > pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
@ -1980,3 +1985,166 @@ details.undocumented[open] > summary::before {
|
|||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Begin: styles for --scrape-examples feature */
|
||||
|
||||
.scraped-example-title {
|
||||
font-family: 'Fira Sans';
|
||||
}
|
||||
|
||||
.scraped-example:not(.expanded) .code-wrapper pre.line-numbers {
|
||||
overflow: hidden;
|
||||
max-height: 240px;
|
||||
}
|
||||
|
||||
.scraped-example:not(.expanded) .code-wrapper .example-wrap pre.rust {
|
||||
overflow-y: hidden;
|
||||
max-height: 240px;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.scraped-example .code-wrapper .prev {
|
||||
position: absolute;
|
||||
top: 0.25em;
|
||||
right: 2.25em;
|
||||
z-index: 100;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.scraped-example .code-wrapper .next {
|
||||
position: absolute;
|
||||
top: 0.25em;
|
||||
right: 1.25em;
|
||||
z-index: 100;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.scraped-example .code-wrapper .expand {
|
||||
position: absolute;
|
||||
top: 0.25em;
|
||||
right: 0.25em;
|
||||
z-index: 100;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.scraped-example .code-wrapper {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scraped-example:not(.expanded) .code-wrapper:before {
|
||||
content: " ";
|
||||
width: 100%;
|
||||
height: 5px;
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
top: 0;
|
||||
background: linear-gradient(to bottom, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
|
||||
}
|
||||
|
||||
.scraped-example:not(.expanded) .code-wrapper:after {
|
||||
content: " ";
|
||||
width: 100%;
|
||||
height: 5px;
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
bottom: 0;
|
||||
background: linear-gradient(to top, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
|
||||
}
|
||||
|
||||
.scraped-example:not(.expanded) .code-wrapper {
|
||||
overflow: hidden;
|
||||
max-height: 240px;
|
||||
}
|
||||
|
||||
.scraped-example .code-wrapper .line-numbers {
|
||||
margin: 0;
|
||||
padding: 14px 0;
|
||||
}
|
||||
|
||||
.scraped-example .code-wrapper .line-numbers span {
|
||||
padding: 0 14px;
|
||||
}
|
||||
|
||||
.scraped-example .code-wrapper .example-wrap {
|
||||
flex: 1;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.scraped-example .code-wrapper .example-wrap pre.rust {
|
||||
overflow-x: inherit;
|
||||
width: inherit;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.scraped-example .example-wrap .rust span.highlight {
|
||||
background: #fcffd6;
|
||||
}
|
||||
|
||||
.scraped-example .example-wrap .rust span.highlight.focus {
|
||||
background: #f6fdb0;
|
||||
}
|
||||
|
||||
.more-examples-toggle {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.more-examples-toggle summary {
|
||||
color: #999;
|
||||
font-family: 'Fira Sans';
|
||||
}
|
||||
|
||||
.more-scraped-examples {
|
||||
margin-left: 25px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: calc(100% - 25px);
|
||||
}
|
||||
|
||||
.more-scraped-examples-inner {
|
||||
/* 20px is width of toggle-line + toggle-line-inner */
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
.toggle-line {
|
||||
align-self: stretch;
|
||||
margin-right: 10px;
|
||||
margin-top: 5px;
|
||||
padding: 0 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.toggle-line:hover .toggle-line-inner {
|
||||
background: #aaa;
|
||||
}
|
||||
|
||||
.toggle-line-inner {
|
||||
min-width: 2px;
|
||||
background: #ddd;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.more-scraped-examples .scraped-example {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.more-scraped-examples .scraped-example:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.example-links a {
|
||||
margin-top: 20px;
|
||||
font-family: 'Fira Sans';
|
||||
}
|
||||
|
||||
.example-links ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* End: styles for --scrape-examples feature */
|
||||
|
|
|
|||
|
|
@ -613,3 +613,22 @@ div.files > .selected {
|
|||
input:checked + .slider {
|
||||
background-color: #ffb454 !important;
|
||||
}
|
||||
|
||||
.scraped-example .example-wrap .rust span.highlight {
|
||||
background: rgb(91, 59, 1);
|
||||
}
|
||||
.scraped-example .example-wrap .rust span.highlight.focus {
|
||||
background: rgb(124, 75, 15);
|
||||
}
|
||||
.scraped-example:not(.expanded) .code-wrapper:before {
|
||||
background: linear-gradient(to bottom, rgba(15, 20, 25, 1), rgba(15, 20, 25, 0));
|
||||
}
|
||||
.scraped-example:not(.expanded) .code-wrapper:after {
|
||||
background: linear-gradient(to top, rgba(15, 20, 25, 1), rgba(15, 20, 25, 0));
|
||||
}
|
||||
.toggle-line-inner {
|
||||
background: #616161;
|
||||
}
|
||||
.toggle-line:hover .toggle-line-inner {
|
||||
background: ##898989;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -485,3 +485,22 @@ div.files > .selected {
|
|||
.setting-line > .title {
|
||||
border-bottom-color: #ddd;
|
||||
}
|
||||
|
||||
.scraped-example .example-wrap .rust span.highlight {
|
||||
background: rgb(91, 59, 1);
|
||||
}
|
||||
.scraped-example .example-wrap .rust span.highlight.focus {
|
||||
background: rgb(124, 75, 15);
|
||||
}
|
||||
.scraped-example:not(.expanded) .code-wrapper:before {
|
||||
background: linear-gradient(to bottom, rgba(53, 53, 53, 1), rgba(53, 53, 53, 0));
|
||||
}
|
||||
.scraped-example:not(.expanded) .code-wrapper:after {
|
||||
background: linear-gradient(to top, rgba(53, 53, 53, 1), rgba(53, 53, 53, 0));
|
||||
}
|
||||
.toggle-line-inner {
|
||||
background: #616161;
|
||||
}
|
||||
.toggle-line:hover .toggle-line-inner {
|
||||
background: ##898989;
|
||||
}
|
||||
|
|
|
|||
86
src/librustdoc/html/static/js/scrape-examples.js
Normal file
86
src/librustdoc/html/static/js/scrape-examples.js
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/* global addClass, hasClass, removeClass, onEach */
|
||||
|
||||
(function () {
|
||||
// Scroll code block to put the given code location in the middle of the viewer
|
||||
function scrollToLoc(elt, loc) {
|
||||
var wrapper = elt.querySelector(".code-wrapper");
|
||||
var halfHeight = wrapper.offsetHeight / 2;
|
||||
var lines = elt.querySelector('.line-numbers');
|
||||
var offsetMid = (lines.children[loc[0]].offsetTop
|
||||
+ lines.children[loc[1]].offsetTop) / 2;
|
||||
var scrollOffset = offsetMid - halfHeight;
|
||||
lines.scrollTo(0, scrollOffset);
|
||||
elt.querySelector(".rust").scrollTo(0, scrollOffset);
|
||||
}
|
||||
|
||||
function updateScrapedExample(example) {
|
||||
var locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
|
||||
var locIndex = 0;
|
||||
var highlights = example.querySelectorAll('.highlight');
|
||||
var link = example.querySelector('.scraped-example-title a');
|
||||
|
||||
if (locs.length > 1) {
|
||||
// Toggle through list of examples in a given file
|
||||
var onChangeLoc = function(changeIndex) {
|
||||
removeClass(highlights[locIndex], 'focus');
|
||||
changeIndex();
|
||||
scrollToLoc(example, locs[locIndex][0]);
|
||||
addClass(highlights[locIndex], 'focus');
|
||||
|
||||
var url = locs[locIndex][1];
|
||||
var title = locs[locIndex][2];
|
||||
|
||||
link.href = url;
|
||||
link.innerHTML = title;
|
||||
};
|
||||
|
||||
example.querySelector('.prev')
|
||||
.addEventListener('click', function() {
|
||||
onChangeLoc(function() {
|
||||
locIndex = (locIndex - 1 + locs.length) % locs.length;
|
||||
});
|
||||
});
|
||||
|
||||
example.querySelector('.next')
|
||||
.addEventListener('click', function() {
|
||||
onChangeLoc(function() {
|
||||
locIndex = (locIndex + 1) % locs.length;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var expandButton = example.querySelector('.expand');
|
||||
if (expandButton) {
|
||||
expandButton.addEventListener('click', function () {
|
||||
if (hasClass(example, "expanded")) {
|
||||
removeClass(example, "expanded");
|
||||
scrollToLoc(example, locs[0][0]);
|
||||
} else {
|
||||
addClass(example, "expanded");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Start with the first example in view
|
||||
scrollToLoc(example, locs[0][0]);
|
||||
}
|
||||
|
||||
var firstExamples = document.querySelectorAll('.scraped-example-list > .scraped-example');
|
||||
onEach(firstExamples, updateScrapedExample);
|
||||
onEach(document.querySelectorAll('.more-examples-toggle'), function(toggle) {
|
||||
// Allow users to click the left border of the <details> section to close it,
|
||||
// since the section can be large and finding the [+] button is annoying.
|
||||
toggle.querySelector('.toggle-line').addEventListener('click', function() {
|
||||
toggle.open = false;
|
||||
});
|
||||
|
||||
var moreExamples = toggle.querySelectorAll('.scraped-example');
|
||||
toggle.querySelector('summary').addEventListener('click', function() {
|
||||
// Wrapping in setTimeout ensures the update happens after the elements are actually
|
||||
// visible. This is necessary since updateScrapedExample calls scrollToLoc which
|
||||
// depends on offsetHeight, a property that requires an element to be visible to
|
||||
// compute correctly.
|
||||
setTimeout(function() { onEach(moreExamples, updateScrapedExample); });
|
||||
}, {once: true});
|
||||
});
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue