diff --git a/resources/web/docs_js/index.js b/resources/web/docs_js/index.js index 1bb601edb282f..862e657acd376 100644 --- a/resources/web/docs_js/index.js +++ b/resources/web/docs_js/index.js @@ -19,10 +19,13 @@ import "../../../../../node_modules/details-polyfill"; // Add support for URLSearchParams Web API in IE import "../../../../../node_modules/url-search-params-polyfill"; -export function init_headers(right_col, lang_strings) { +// Vocab: +// TOC = table of contents +// OTP = on this page +export function init_headers(sticky_content, lang_strings) { // Add on-this-page block - var this_page = $('
').prependTo(right_col); - this_page.append('

' + lang_strings('On this page') + '

'); + var this_page = $('
').prependTo(sticky_content); + this_page.append('

' + lang_strings('On this page') + '

'); var ul = $('').appendTo(this_page); var items = 0; var baseHeadingLevel = 0; @@ -57,7 +60,7 @@ export function init_headers(right_col, lang_strings) { .remove(); var text = title_container.html(); const adjustedLevel = hLevel - baseHeadingLevel; - const li = '
  • ' + text + '
  • '; + const li = '
  • ' + text + '
  • '; ul.append(li); } } @@ -170,6 +173,44 @@ function init_toc(lang_strings) { }); } +// In the OTP, highlight the heading of the section that is +// currently visible on the page. +// If more than one is visible, highlight the heading for the +// section that is higher on the page. +function highlight_otp() { + let visibleHeadings = [] + const observer = new IntersectionObserver(entries => { + entries.forEach(entry => { + const id = entry.target.getAttribute('id'); + const element = document.querySelector(`#sticky_content #this_page a[href="#${id}"]`); + const itemId = $(element).parent().attr('id') + // All heading elements have an `entry` (even the title). + // The title does not exist in the OTP, so we must exclude it. + // Checking for the existence of `itemId` ensures we don't parse elements that don't exist. + if (itemId){ + const itemNumber = parseInt(itemId.match(/\d+/)[0], 10); + if (entry.intersectionRatio > 0){ + visibleHeadings.push(itemNumber); + } else { + const position = visibleHeadings.indexOf(itemNumber); + visibleHeadings.splice(position, 1) + } + if (visibleHeadings.length > 0) { + visibleHeadings.sort((a, b) => a - b) + // Remove existing active classes + $('a.active').removeClass("active"); + // Add active class to the first visible heading + $('#otp-text-' + visibleHeadings[0] + ' > a').addClass('active') + } + } + }) + }) + + document.querySelectorAll('#guide a[id]').forEach((heading) => { + observer.observe(heading); + }) +} + // Main function, runs on DOM ready $(function() { var lang = $('section#guide[lang]').attr('lang') || 'en'; @@ -228,7 +269,16 @@ $(function() { AlternativeSwitcher(store()); - var right_col = $('#right_col'); // Move rtp container to top right and make visible + // Move rtp container to top right and make visible + var sticky_content = $('#sticky_content'); + // Left column that contains the TOC + var left_col = $('#left_col'); + // Middle column that contains the main content + var middle_col = $('#middle_col'); + // Right column that contains the OTP and demand gen content + var right_col = $('#right_col'); + // Empty column below TOC on small screens so the demand gen content can be positioned under the main content + var bottom_left_col = $('#bottom_left_col'); $('.page_header > a[href="../current/index.html"]').click(function() { utils.get_current_page_in_version('current'); @@ -271,14 +321,24 @@ $(function() { if (div.length == 0 && $('#guide').find('div.article,div.book').length == 0) { var url = location.href.replace(/[^\/]+$/, 'toc.html'); var toc = $.get(url, {}, function(data) { - right_col.append(data); + left_col.append(data); init_toc(LangStrings); utils.open_current(location.pathname); }).always(function() { - init_headers(right_col, LangStrings); + init_headers(sticky_content, LangStrings); + highlight_otp(); }); } else { init_toc(LangStrings); + // Style book landing page (no main content, just a TOC and demand gen content) + + // Set the width of the left column to zero + left_col.removeClass().addClass('col-0'); + bottom_left_col.removeClass().addClass('col-0'); + // Set the width of the middle column (containing the TOC) to 9 + middle_col.removeClass().addClass('col-12 col-lg-9 guide-section'); + // Set the width of the demand gen content to 3 + right_col.removeClass().addClass('col-12 col-lg-3 sticky-top-md h-almost-full-lg'); } PR.prettyPrint(); @@ -299,6 +359,26 @@ $(function() { $('a.edit_me_private').show(); } + // scroll to selected TOC element; if it doesn't exist yet, wait and try again + // window.width must match the breakpoint of `.sticky-top-md` + if($(window).width() >= 769){ + var scrollToSelectedTOC = setInterval(() => { + if ($('.current_page').length) { + // Get scrollable element + var container = document.querySelector("#left_col"); + // Get active table of contents element + var activeItem = document.querySelector(".current_page") + // If the top of the active item is out of view (or in the bottom 100px of the visible portion of the TOC) + // scroll so the top of the active item is at the top of the visible portion TOC + if (container.offsetHeight - 100 <= activeItem.offsetTop) { + // Scroll to active item + container.scrollTop = activeItem.offsetTop + } + clearInterval(scrollToSelectedTOC); + } + }, 150); + } + // Test comment used to detect unminifed JS in tests }); diff --git a/resources/web/docs_js/utils.js b/resources/web/docs_js/utils.js index 28b71b0769bf4..9d1b339d8ffe0 100644 --- a/resources/web/docs_js/utils.js +++ b/resources/web/docs_js/utils.js @@ -18,6 +18,7 @@ export function open_current(pathname) { var page = pathname.match(/[^\/]+$/)[0]; var current = $('div.toc a[href="' + page + '"]'); current.addClass('current_page'); + current.parent().parent().addClass('current_page_li'); current.parentsUntil('ul.toc', 'li.collapsible').addClass('show'); } diff --git a/resources/web/style/base_styles.pcss b/resources/web/style/base_styles.pcss index ac2fa3a522598..78735f5f98820 100644 --- a/resources/web/style/base_styles.pcss +++ b/resources/web/style/base_styles.pcss @@ -30,4 +30,60 @@ details { margin-bottom: 1.15em; } + + .container-fluid { + @media screen and (min-width: 1560px) { + max-width: 1500px; + } + } + + .sticky-top-md { + position: -webkit-relative; + position: relative; + @media screen and (min-width: 769px) { + position: -webkit-sticky; + position: sticky; + top: 0; + } + } + + .sticky-top-lg { + position: -webkit-relative; + position: relative; + @media screen and (min-width: 993px) { + position: -webkit-sticky; + position: sticky; + top: 0; + } + } + + .h-almost-full-md { + @media screen and (min-width: 769px) { + height: 95vh; + } + } + + .h-almost-full-lg { + @media screen and (min-width: 993px) { + height: 95vh; + } + } + + #left_col { + overflow: auto; + } + + .aside-heading { + font-weight: 600; + margin-top: 20px; + margin-bottom: 10px; + } + + .media-type { + opacity: 0.6; + text-transform: uppercase; + font-size: 80%; + font-weight: 400; + margin-bottom: 0px; + } } diff --git a/resources/web/style/docbook.pcss b/resources/web/style/docbook.pcss index 0625154569591..332c2aee60605 100644 --- a/resources/web/style/docbook.pcss +++ b/resources/web/style/docbook.pcss @@ -18,3 +18,7 @@ .guide-section { margin-bottom: 30px; } + +#sticky_content { + padding-bottom: 30px; +} \ No newline at end of file diff --git a/resources/web/style/heading.pcss b/resources/web/style/heading.pcss index a470c8d8cbb45..7cbcb45f868ab 100644 --- a/resources/web/style/heading.pcss +++ b/resources/web/style/heading.pcss @@ -77,4 +77,11 @@ background-image: inline("img/edit-me-private.png"); display: none; } -} + + /* Titlepage headings don't need large gaps around them */ + .titlepage { + .title { + margin: 10px 0 16px; + } + } +} \ No newline at end of file diff --git a/resources/web/style/link.pcss b/resources/web/style/link.pcss index 81af3d48cea82..d83e8bb423895 100644 --- a/resources/web/style/link.pcss +++ b/resources/web/style/link.pcss @@ -1,6 +1,6 @@ #guide { a { - color: #00a9e5; + color: #0077CC; font-weight: normal; text-decoration: none; outline: none; diff --git a/resources/web/style/on_this_page.pcss b/resources/web/style/on_this_page.pcss index 93ae336d65c55..28dcaaa8aaaf6 100644 --- a/resources/web/style/on_this_page.pcss +++ b/resources/web/style/on_this_page.pcss @@ -5,16 +5,16 @@ .heading-level-1 { display: block; - padding-left: 1.5em !important; + padding-left: 1em !important; } .heading-level-2 { display: block; - padding-left: 3em !important; + padding-left: 2em !important; } .heading-level-3 { display: block; - padding-left: 4.5em !important; + padding-left: 3em !important; } } \ No newline at end of file diff --git a/resources/web/style/rtpcontainer.pcss b/resources/web/style/rtpcontainer.pcss index c07831fffa092..3b9e2660f3ca4 100644 --- a/resources/web/style/rtpcontainer.pcss +++ b/resources/web/style/rtpcontainer.pcss @@ -5,9 +5,7 @@ * on the rtpcontainer in general. */ #rtpcontainer { .mktg-promo { - margin: 55px 0 30px; - padding: 32px; - border: 1px solid #d4dae5; + padding: 12px; } h3 { margin: 5px 0; @@ -47,7 +45,7 @@ li { align-items: center; list-style: none; - min-height: 50px; + min-height: 30px; padding-left: 0.6em; display: flex; font-size: 14px; diff --git a/resources/web/style/this_page.pcss b/resources/web/style/this_page.pcss index add5ce946f394..db62f1572cf63 100644 --- a/resources/web/style/this_page.pcss +++ b/resources/web/style/this_page.pcss @@ -1,6 +1,12 @@ #this_page { - margin-bottom: 0; - padding-left: 1em; + padding-bottom: 20px; + display: block; + border-bottom: 1px solid #dee2e6; + max-height:40vh; + overflow: auto; + @media screen and (max-width: 992px) { + display: none; + } h2 { font-size: 1.5em; line-height: 1.5em; @@ -13,6 +19,11 @@ } li { line-height: 1.2em; - margin-bottom: .5em; + margin-top: .3em; + margin-bottom: .3em; + } + .active { + font-weight: 700; + font-style: ul; } } diff --git a/resources/web/style/toc.pcss b/resources/web/style/toc.pcss index 36bb2c5ccd0e6..090b1aff39d09 100644 --- a/resources/web/style/toc.pcss +++ b/resources/web/style/toc.pcss @@ -1,23 +1,43 @@ #guide { + .book-title { + font-size: 120%; + font-weight: 600; + margin: 20px 0px 20px 20px; + } .toc { ul { - margin: 0 0 1em 0; + margin: 0 0 3px 0; padding: 0; - border: 1px solid #ddd; ul { /* Hide all sub-toc elements by default. See rules with `.show` that * show specific sub-toc elements. */ display: none; + li { + padding: 0 10px; + } } } li { - margin: 0; - padding: 0; + margin: 3px 0px; + padding: 3px 15px 3px 15px; list-style: none; + a { + color: rgb(52, 55, 65) !important; + } ul { border: none; } + &:not(#book_title):hover { + background-color: #F1F4FA; + border-radius: 20px; + } } + + li.current_page_li { + background-color: #F1F4FA; + border-radius: 20px; + } + span { display: block; padding: 0.5em 0; @@ -30,22 +50,43 @@ } .collapsible.show { + background-color: #F1F4FA; + border-radius: 20px; + padding-bottom: 5px; > ul { display: block; } - > span { - background-image: inline("img/minus.png"); - background-color: white; - border-bottom: 1px solid white; + &:not(#book_title) { + > span { + &:after { + content: url('data:image/svg+xml;utf8,'); + display: inline-block; + float: right; + padding-top: 3px; + width: 16px; + height: 16px; + } + } } } .collapsible { - > span { - background-repeat: no-repeat; - background-image: inline("img/plus.png"); - &:hover { - background-color: #fafafa; - cursor: pointer; + &:not(#book_title) { + > span { + a { + max-width: 85%; + display: inline-block; + } + &:hover { + cursor: pointer; + } + &:after { + content: url('data:image/svg+xml;utf8,'); + display: inline-block; + padding-top: 3px; + float: right; + width: 16px; + height: 16px; + } } } } @@ -53,29 +94,22 @@ /* Customize each level of the TOC, mostly so it looks "indented". */ > li { > span { - background-color: #efefef; - border-bottom: 1px solid #ddd; font-size: 1em; background-position: 0 11px; - padding-left: 20px; } > ul > li { > span { - padding-left: 40px; background-position: 20px 8px; } > ul > li { > span { - padding-left: 60px; background-position: 40px 8px; } > ul > li { > span { - padding-left: 80px; background-position: 60px 8px; } ul > li > span { - padding-left: 80px; background-image: none; } } @@ -87,7 +121,7 @@ .beta, .coming, .deprecated, - .dev, + .dev, .experimental { display: none; } @@ -107,18 +141,25 @@ } #book_title { - color: #2b4590; + color: rgb(52, 55, 65); + font-weight: 600; + display: block; + border-bottom-width: 1px; + border-bottom-style: solid; + border-bottom-color: #dee2e6; select { - background-color: #fcfcfc; - border: none; - margin-left: 1px; - color: #2b4590; - width: 150px; + width: 100%; + display: block; + color: #495057; + background-color: #fff; + border: 1px solid #495057; + border-radius: 5px; + padding: 3px; + margin-top: 6px; } #other_versions { /* We'll show it if you click "other versions". */ display: none; } } - diff --git a/resources/web/template.html b/resources/web/template.html index 29c2dedec47aa..423f1469cbd0d 100644 --- a/resources/web/template.html +++ b/resources/web/template.html @@ -82,22 +82,48 @@
    > -
    -
    -
    +
    +
    +
    + +
    + +
    -