Skip to content

Commit

Permalink
Merge pull request #6202 from jimchamp/6170/feature/navbar
Browse files Browse the repository at this point in the history
Raise book page navbar higher on page
  • Loading branch information
mekarpeles authored Mar 3, 2022
2 parents 9725bf2 + 7f8e4f8 commit b38c6fc
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 16 deletions.
6 changes: 3 additions & 3 deletions openlibrary/macros/EditionNavBar.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

<ul class="work-menu sticky">
<li class="selected">
<a href="#edition-overview">$_("Overview")</a>
</li>
<li>
<a href="#editions-list">
$ungettext('View %(count)s Edition', 'View %(count)s Editions', edition_count, count=edition_count)
</a>
</li>
<li>
<a href="#work-details">$_("Overview")</a>
</li>
<li>
<a href="#edition-details">$_("This Edition")</a>
</li>
Expand Down
86 changes: 86 additions & 0 deletions openlibrary/plugins/openlibrary/js/edition-nav-bar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { debounce } from '../nonjquery_utils'

/**
* Adds navbar-related click and scroll listeners
*
* @param {HTMLUListElement} navbarElem The navbar
*/
export function initNavbar(navbarElem) {
/**
* Each list item in the navbar.
*
* @type {HTMLCollection<HTMLLIElement}
*/
const listItems = navbarElem.querySelectorAll('li');

/**
* The targets of the navbar links.
*
* @type {Array<HTMLElement>}
*/
const linkedSections = []

/**
* Reference to the selected target element.
*
* @type {HTMLElement}
*/
let selectedSection

// Add click listeners
for (let i = 0; i < listItems.length; ++i) {
const index = i;
listItems[i].addEventListener('click', function() {
debounce(selectElement(listItems[i], index), 300, false)
})

linkedSections.push(document.querySelector(listItems[i].children[0].hash))
if (listItems[i].classList.contains('selected')) {
selectedSection = linkedSections[linkedSections.length - 1]
}
}

/**
* Adds 'selected' class to the given element.
*
* Removes 'selected' class from all navbar links, then adds
* 'selected' to the newly selected link.
*
* Stores reference to the selected target.
*
* @param {HTMLLIElement} selectedElem Element corresponding to the 'selected' navbar item.
* @param {Number} targetIndex The index
*/
function selectElement(selectedElem, targetIndex) {
for (const li of listItems) {
li.classList.remove('selected')
}
selectedElem.classList.add('selected')
selectedSection = linkedSections[targetIndex];
}

// Add scroll listener that changes 'selected' navbar item based on page position:
document.addEventListener('scroll', function() {
const navbarBoundingRect = navbarElem.getBoundingClientRect()
const selectedBoundingRect = selectedSection.getBoundingClientRect();

// Check if navbar is not within selected element's bounds:
if (selectedBoundingRect.bottom < navbarBoundingRect.top ||
selectedBoundingRect.top > navbarBoundingRect.bottom) {
for (let i = 0; i < linkedSections.length; ++i) {
// Do not do bounds check on selected item:
if (linkedSections[i].id !== selectedSection.id) {
const br = linkedSections[i].getBoundingClientRect()

// If navbar overlaps with an unselected target section, select that section:
if (br.top < navbarBoundingRect.bottom && br.bottom > navbarBoundingRect.bottom) {
selectElement(listItems[i], i)
break;
}
}
}
}
})
}


6 changes: 6 additions & 0 deletions openlibrary/plugins/openlibrary/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,4 +323,10 @@ jQuery(function () {
import(/* webpackChunkName: "star-ratings" */'./handlers')
.then((module) => module.initRatingHandlers(ratingForms));
}

const navbar = document.querySelector('.work-menu');
if (navbar) {
import(/* webpackChunkName: "nav-bar" */ './edition-nav-bar')
.then((module) => module.initNavbar(navbar));
}
});
5 changes: 0 additions & 5 deletions openlibrary/plugins/openlibrary/js/ol.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ export function initReadingListFeature() {
$(this).closest('.arrow').toggleClass('up');
}, 300, false));

$(document).on('click', '.work-menu li', debounce(function() {
$('.work-menu li').removeClass('selected');
$(this).addClass('selected');
}, 300, false));

// Close any open dropdown list if the user clicks outside...
$(document).on('click', function() {
closeDropdown($('.widget-add'));
Expand Down
2 changes: 1 addition & 1 deletion openlibrary/templates/observations/review_component.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
$else:
$ total_reviews = 0

<a name="reader-observations" class="section-anchor"></a>
<a id="reader-observations" name="reader-observations" class="section-anchor"></a>

<div class="tab-section review-component">
<div class="reviews-header">
Expand Down
9 changes: 4 additions & 5 deletions openlibrary/templates/type/edition/view.html
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ <h2 class="edition-byline">$_("by") $:authors_byline</h2>
$:macros.StarRatingsStats(work)
$ component_times['ReadlogStats'] = time() - component_times['ReadlogStats']

$:macros.EditionNavBar(work.edition_count, show_observations)
<a id="edition-overview" name="edition-overview"></a>
<div class="edition-omniline">
$:render_template("type/edition/publisher_line", edition)

Expand Down Expand Up @@ -225,8 +227,6 @@ <h4 class="year">&mdash;
</div>
$:macros.ReadMore("subjects")
</div>
$:macros.EditionNavBar(work.edition_count, show_observations)

$if ebooks_only:
<p>
$ungettext("Showing one ebook only.", "Showing %(count)d ebooks only", len(editions), count=len(editions)) <a href="?mode=all">$_("View all %(count)d editions?", count=work.edition_count)</a>
Expand All @@ -242,12 +242,11 @@ <h4 class="year">&mdash;
<a href="$work.key?edition=$(e.ocaid)">$e.languages[0].name</a>
</p>

<a name="editions-list" class="section-anchor"></a>
<a id="editions-list" name="editions-list" class="section-anchor"></a>
$ component_times['EditionsTable'] = time()
$:render_template("type/work/editions_datatable", work, editions=editions, edition=edition)
$ component_times['EditionsTable'] = time() - component_times['EditionsTable']

<a name="work-details" class="section-anchor"></a>
<div class="tab-section work-info">
<h2 class="work-title"><a href="$work.key">$work_title</a></h2>
$if work and work.subtitle:
Expand Down Expand Up @@ -330,7 +329,7 @@ <h4 class="collapse">$_("Classifications")</h4>
</div>
</div>

<a name="edition-details" class="section-anchor"></a>
<a id="edition-details" name="edition-details" class="section-anchor"></a>
<div class="tab-section edition-info">
$if not page.is_fake_record():
$if page.type.key in ["/type/work", "/type/edition", "/type/author"]:
Expand Down
3 changes: 1 addition & 2 deletions static/css/components/work.less
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,8 @@ div.editionTools {

.edition-omniline {
display: flex;
border-top: 1px solid @lighter-grey;
border-bottom: 1px solid @lighter-grey;
margin: 20px 0 10px;
margin-bottom: 10px;

h4 {
padding-right: 5px;
Expand Down

0 comments on commit b38c6fc

Please sign in to comment.