Files
website-v2/templates/includes/_header.html

595 lines
20 KiB
HTML

{% load static %}
{% load account socialaccount active_link_tags %}
<style>
@import url({% static 'css/fonts.css' %});
:root {
--site-light-bg-color: rgb(229, 231, 235);
--site-dark-bg-color: rgb(5, 26, 38);
--site-light-card-color: #fff;
--site-dark-card-color: rgb(23, 42, 52);
--site-light-border-color: #d1d1d1;
--site-dark-border-color: #07405f;
--site-light-text-color: rgb(49, 74, 87);
--site-dark-text-color: #ccc;
--site-dark-heading-text-color: #fff;
--site-light-heading-text-color: rgb(49, 74, 87);
--site-primary-orange: rgb(255, 159, 0);
--site-light-secondary-blue: rgb(2, 132, 199);
--site-dark-secondary-blue: rgb(125, 211, 252);
--site-light-teritary-green: rgb(14, 174, 96);
--site-dark-teritary-green: rgb(90, 213, 153);
--site-light-shadow-color: rgba(0,0,0,0.3);
--site-dark-shadow-color: transparent;
/* specific use colors */
/* header height var for docs positioning */
--header-height: 2.5rem;
}
html {
--bg-color: var(--site-light-bg-color);
--card-color: var(--site-light-card-color);
--border-color: var(--site-light-border-color);
--text-color: var(--site-light-text-color);
--header-color: var(--site-light-heading-text-color);
--primary-color: var(--site-primary-orange);
--secondary-color: var(--site-light-secondary-blue);
--teritary-color: var(--site-light-teritary-green);
--shadow-color: var(--site-light-shadow-color);
/* specific use colors */
}
html.dark {
--bg-color: var(--site-dark-bg-color);
--card-color: var(--site-dark-card-color);
--border-color: var(--site-dark-border-color);
--text-color: var(--site-dark-text-color);
--header-color: var(--site-dark-heading-text-color);
--primary-color: var(--site-primary-orange);
--secondary-color: var(--site-dark-secondary-blue);
--teritary-color: var(--site-dark-teritary-green);
--shadow-color: var(--site-dark-shadow-color);
/* specific use colors */
}
.header-menu-bar {
padding: 0 1rem;
height: 41px;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0px 1px 0px #d1d1d1;
border-bottom: 1px solid #f6f6f6;
max-width: 80rem;
margin: 0 auto;
color: var(--text-color);
font-family: "Noto Sans" !important;
}
.DEBUG .header-menu-bar {
font-family: "Noto Sans", serif !important;
}
.dark .header-menu-bar {
border-bottom: 1px solid #07405f;
box-shadow: 0 1px 0 #000;
}
.header-menu-bar .left-menubar {
display: flex;
align-items: center;
justify-content: flex-start;
flex-grow: 1;
}
.header-menu-bar .right-menubar {
display: flex;
align-items: center;
justify-content: flex-end;
max-width: 9rem;
}
.header-menu-bar .logo-link {
width: 1.3rem;
height: 1.6rem;
}
.header-menu-bar .menu-link {
text-transform: capitalize;
text-decoration: none;
margin-left: 1rem;
font-weight: 500;
color: var(--text-color);
font-size: 18px;
}
.header-menu-bar .menu-link-right {
text-transform: capitalize;
margin-right: 1rem;
font-weight: 500;
color: var(--text-color);
font-size: 18px;
white-space: nowrap;
}
.icon-link {
display:block;
margin-left: 1rem;
cursor: pointer
}
.dark .icon-link {
opacity: 0.5;
}
.icon-link:hover,
.menu-link:hover,
.active-link,
.mobile-menu-item a:hover {
color: var(--primary-color) !important;
opacity: 1;
}
.boost-drop-shadow {
box-shadow: 2px 2px 5px 1px var(--shadow-color);
}
.guide-modal {
position: absolute;
right:0;
z-index: 10;
padding: .25rem .5rem;
margin-top: .5rem;
width: 10rem;
text-align:left;
background-color: var(--card-color);
border-radius: 0.375rem;
border: 1px solid var(--border-color);
box-shadow: 3px 3px 7px 1px var(--shadow-color);
}
.guide-modal a {
margin-left: .5rem;
display: block;
padding: .5rem 0;
font-size: .8rem;
cursor: pointer;
color: var(--text-color);
border-bottom: var(--border-color) 1px solid;
}
.guide-modal a:last-child {
border-bottom: none;
}
.guide-modal a:hover {
color: var(--primary-color);
}
#pageselector {
text-transform: capitalize;
margin-left: 1rem;
font-weight: 500;
display:flex;
position: absolute;
top: 2.25rem;
left: 1.75rem;
flex-direction: column;
z-index: 10;
color: var(--text-color);
background-color: var(--card-color);
font-size: 1rem;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
}
.hide {
display: none !important;
}
.mobile-menu-item {
min-width: 10rem;
padding: .5rem 1rem;
border-bottom: var(--border-color) 1px solid;
text-transform: capitalize;
}
.mobile-menu-item:last-child {
border-bottom: none;
}
#avatar svg {
width: 1rem;
height: 1rem;
color: var(--text-color);
fill: var(--primary-color);
}
#mobileNav {
display: flex;
align-items: center;
}
#selectedpage {
display: flex;
align-items: center;
justify-content: space-between;
padding-left: 10px;
font-weight: 500;
font-size: 18px;
}
#pageName {
text-transform: capitalize;
}
#desktopNav {
display: none;
}
@media screen and (min-width: 768px) {
#mobileNav {
display: none;
}
#desktopNav {
display: flex;
}
}
/* specific to docs */
body.article {
max-width: 100% !important;
margin: 0;
padding: 0px .75rem !important;
}
body .body {
margin: 0px 1rem;
padding: 1.5rem 0rem 0;
max-width: 80rem;
}
body.article #headblock {
padding: 0.25rem 1rem !important;
}
article.card {
border-radius: .5rem;
padding-top: .5rem !important;
}
@media (min-width: 769px) {
body.article {
max-width: 80rem !important;
margin: auto;
padding: 0px 2.25rem;
border-radius: .5rem;
}
}
@media (max-width: 768px) {
body.article {
padding: 0px !important;
border-radius: 0rem !important;
margin: 0 !important;
}
body.article #headblock {
padding: 0.25rem 0.5rem !important;
}
.body {
margin: 0 !important;
padding: 0 !important;
}
.article .card {
border-radius: 0 !important;
}
}
/* asciidoc layout base */
#boost-legacy-docs-wrapper {
margin: auto;
max-width: 80rem;
overflow: hidden;
position: relative;
margin-top: 1rem;
}
#boost-legacy-docs-wrapper:not(:has(article.doc)) #toc.toc2 {
position: fixed !important;
top: 3.5rem;
border-top-width: 0 !important;
border-bottom-width: 0 !important;
z-index: 1000;
padding: 1.25em 1em;
max-height: calc(100vh - 4rem);
height: fit-content;
overflow: auto;
position: absolute;
left: 1rem;
-webkit-transform: translateZ(0);
}
#boost-legacy-docs-wrapper #header>h1:first-child {
margin-top: .5rem !important;
color: var(--header-color) !important;
}
#boost-legacy-docs-wrapper > #header,
#boost-legacy-docs-wrapper > #content,
#boost-legacy-docs-wrapper > #footer,
#boost-legacy-docs-wrapper > #footnotes {
width: auto;
max-width: 62rem;
margin-left: 15rem;
}
.main-footer {
max-width: 80rem !important;
}
.link-icons {
width: 4rem;
}
.links {
padding: 0 0.5rem;
}
.source-docs-antora .doc {
padding-top: 0 !important;
}
@media screen and (max-width: 940px) {
.links {
flex-direction: column;
align-items: center;
}
}
@media screen and (min-width: 1280px) {
#boost-legacy-docs-wrapper:not(:has(article.doc)) #toc.toc2 {
position: fixed !important;
width: 20em;
left: calc((100% - 79rem) / 2) !important;
-webkit-transform: translateZ(0);
}
#boost-legacy-docs-wrapper > #header,
#boost-legacy-docs-wrapper > #content,
#boost-legacy-docs-wrapper > #footer,
#boost-legacy-docs-wrapper > #footnotes {
margin-left: 20rem;
max-width: 59rem !important;
}
}
@media screen and (max-width: 769px) {
#boost-legacy-docs-wrapper:not(:has(article.doc))#toc.toc2 {
width: 100%;
left: 0;
top: 0;
margin-top: 4rem;
-webkit-transform: none;
padding: 0;
padding-left: 1rem;
}
.source-docs-asciidoc #header #toc.toc2 {
position: relative !important;
height: auto;
}
#boost-legacy-docs-wrapper {
margin-top:0;
}
#boost-legacy-docs-wrapper > #header,
#boost-legacy-docs-wrapper > #content,
#boost-legacy-docs-wrapper > #footer,
#boost-legacy-docs-wrapper > #footnotes {
margin-left: 0rem;
max-width: 100% !important;
}
.main-footer {
margin-left: 0 !important;
margin: auto !important
}
}
</style>
<div class="header-menu-bar topnavbar">
<!-- mobile navbar -->
<div id="mobileNav" >
<a href="{% url 'home' %}" title="Boost Home" class="logo-link"><img style="width:1.3rem" src="{% static 'img/Boost_Symbol_Transparent.svg' %}" alt="Boost"></a>
<div id="selectedpage" onclick="openNav()" class=""><div id="pageName" class="capitalize">boost</div><div class="material-symbols-outlined">arrow_drop_down</div></div>
<div id="pageselector" onmouseleave="closeNav()" class="hide boost-drop-shadow" >
<div class="mobile-menu-item"><a href="{% url 'news' %}" title="News">News</a></div>
<div class="mobile-menu-item"><a href="{% url 'docs' %}" title="Learn">Learn</a></div>
<div class="mobile-menu-item"><a href="{% url 'community' %}" title="Community">Community</a></div>
<div class="mobile-menu-item"><a href="{% url 'libraries' %}" title="Libraries">Libraries</a></div>
<div class="mobile-menu-item"><a href="{% url 'releases-most-recent' %}" title="Releases">Releases</a></div>
</div>
</div>
<!-- desktop navbar -->
<div id="desktopNav" class="left-menubar">
<a href="{% url 'home' %}" title="Boost Home" class="logo-link"><img style="width:1.3rem" src="{% static 'img/Boost_Symbol_Transparent.svg' %}" alt="Boost"></a>
<a href="{% url 'news' %}" id="news" class="menu-link {% active_link 'news' css_class=' menu-link active-link' inactive_class='menu-link' %}">news</a>
<a href="{% url 'docs' %}" id="learn" class="menu-link {% active_link 'docs||docs-user-guide' css_class=' menu-link active-link' inactive_class='menu-link' %}">learn</a>
<a href="{% url 'community' %}" id="community" class="menu-link {% active_link 'community' css_class=' menu-link active-link' inactive_class='menu-link' %}">community</a>
<a href="{% url 'libraries' %}" id="libraries" class="menu-link {% active_link 'libraries||docs-libs-page' css_class=' menu-link active-link' inactive_class='menu-link' %}">libraries</a>
<a href="{% url 'releases-most-recent' %}" id="releases" class="menu-link {% active_link 'releases-most-recent' css_class=' menu-link active-link' inactive_class='menu-link' %}">releases</a>
</div>
<div class="right-menubar" x-data="{ 'searchOpen': false }">
<span style="position: relative;" x-ref="desktopSearchArea">
<i id="gecko-search-button" data-current-boost-version="{{ current_version.stripped_boost_url_slug }}" data-theme-mode="light" data-font-family="sans-serif" class="fas fa-search icon-link"></i>
<script>
const geckoSearchButton = document.getElementById('gecko-search-button');
geckoSearchButton.setAttribute('data-theme-mode', localStorage.getItem('colorMode') === 'dark' ? 'dark' : 'light');
</script>
</span>
<span x-data="{ 'guideOpen': false }" style="position:relative;">
<i class="icon-link fas fa-question-circle" @click="guideOpen = !guideOpen"></i>
<div x-show="guideOpen" x-cloak @click.away="guideOpen = false" id="guideMenu" class="guide-modal boost-drop-shadow hidden">
<a href="/doc/user-guide/index.html">User Guide</a>
<a href="/doc/contributor-guide/index.html">Contributor Guide</a>
<a href="{% url 'review-process' %}">Formal Reviews</a>
</div>
</span>
{% if not disable_theme_switcher %}
<i id="light-dark" class="fas fa-sun icon-link " onclick="changeTheme()"></i>
{% endif %}
<span x-data="{ 'userOpen': false }" class="menu-link w-8 relative">
{# HTMX to load the avatar content, allows cached docs/guides pages to load the user status #}
<div hx-get="/users/avatar/"
hx-trigger="load"
hx-target="#avatar"
hx-indicator="#avatar">
</div>
<span id="avatar"></span>
</span>
</div>
</div>
<script>
document.addEventListener("alpine:init", function() {
Alpine.data("searchToggleComponent", () => ({
searchButton: null,
desktopSearchArea: null,
mobileSearchArea: null,
init() {
this.searchButton = document.getElementById("gecko-search-button");
this.desktopSearchArea = this.$el.querySelector('[x-ref="desktopSearchArea"]');
this.mobileSearchArea = this.$el.querySelector('[x-ref="mobileSearchArea"]');
this.updateSearchButtonLocation();
},
updateSearchButtonLocation() {
if (window.innerWidth > 769) {
this.desktopSearchArea.appendChild(this.searchButton);
} else {
this.mobileSearchArea.appendChild(this.searchButton);
}
}
}))
});
// ************ Mobile Navigation **************
let containingElement = document.getElementById("pageselector");
document.body.addEventListener('click', function( event ){
if(!containingElement.contains( event.target ) ){
closeNav();
}
});
var url = window.location.pathname;
if (url != "srcdoc") {
var words = url.split("\/");
words[1] = words[1].replaceAll("\/", "");
var tabname = "Home"
var pagename = document.getElementById("pageName")
if (words[1].length != '') {
switch (words[1]) {
case 'doc':
if (words[2] == 'libs') {
tabname = "libraries"
} else {
tabname = "learn"
}
break;
case 'docs':
tabname = "learn"
break;
case 'community':
tabname = "community"
break;
case 'news':
tabname = "news"
break;
case 'libraries':
tabname = "libraries"
break;
case 'releases':
tabname = "releases"
break;
case 'accounts':
tabname= 'account'
break;
}
var activename = document.getElementById(tabname);
activename.classList.add('active-link');
}
pagename.innerText='';
pagename.appendChild(document.createTextNode(tabname));
}
function openNav() {
ps = document.getElementById("pageselector");
ps.classList.remove('hide');
}
function closeNav() {
ps = document.getElementById("pageselector");
setTimeout(function() {
if (!ps.matches(':hover')) {
ps.classList.add('hide');
}
}, 2000);
}
// *********** manage theming *************
function makeDark() {
localStorage.setItem("colorMode", "dark");
// interval is used here to cause a tiny delay to allow iframe dark mode to
// be set closer to when the parent dark mode is set
setTimeout(() => {
document.documentElement.classList.add('dark');
var iconchange = document.getElementById("light-dark")
iconchange.classList.remove('fa-moon');
iconchange.classList.add('fa-sun');
}, 0)
}
function makeLight() {
localStorage.setItem("colorMode", "light");
// timeout is used here to cause a tiny delay to allow iframe dark mode to
// be set closer to when the parent dark mode is set
setTimeout(() => {
document.documentElement.classList.remove('dark');
var iconchange = document.getElementById("light-dark")
iconchange.classList.remove('fa-sun');
iconchange.classList.add('fa-moon');
}, 0);
}
function changeTheme() {
if (document.documentElement.classList.contains("dark")) {
makeLight();
return;
}
makeDark();
}
function setTheme(theme) {
if (theme == "dark") {
makeDark();
return;
} else if (theme == "light") {
makeLight();
return;
} else {
makeLight();
}
}
function checkmedia() {
const relevantWindow = window.parent || window;
if (relevantWindow.matchMedia) {
// Check if the dark-mode Media-Query matches
if(relevantWindow.matchMedia('(prefers-color-scheme: dark)').matches){
if(localStorage.getItem("colorMode") === null || localStorage.getItem("colorMode") == "dark" ) {
makeDark();
localStorage.removeItem("colorMode")
} else {
makeLight();
};
} else if (relevantWindow.matchMedia('(prefers-color-scheme: light)').matches) {
if(localStorage.getItem("colorMode") === null || localStorage.getItem("colorMode") == "light" ) {
makeLight();
localStorage.removeItem("colorMode")
} else {
makeDark();
};
} else {
setTheme(localStorage.getItem("colorMode"));
}
}
}
if (window.parent) {
window.addEventListener('storage', function(e) {
if (e.key === 'colorMode') {
if (localStorage.getItem("colorMode") === "light"){
document.documentElement.classList.remove('dark');
}
else {
document.documentElement.classList.add('dark');
}
}
});
}
checkmedia();
function removejscssfile(filename, filetype){
var targetelement=(filetype=="js")? "script" : (filetype=="css")? "link" : "none" //determine element type to create nodelist from
var targetattr=(filetype=="js")? "src" : (filetype=="css")? "href" : "none" //determine corresponding attribute to test for
var allsuspects=document.getElementsByTagName(targetelement)
for (var i=allsuspects.length; i>=0; i--){ //search backwards within nodelist for matching elements to remove
if (allsuspects[i] && allsuspects[i].getAttribute(targetattr)!=null && allsuspects[i].getAttribute(targetattr).indexOf(filename)!=-1)
allsuspects[i].parentNode.removeChild(allsuspects[i]) //remove element by calling parentNode.removeChild()
}
}
document.onreadystatechange = () => {
if (document.readyState === 'complete') {
removejscssfile("boostbook.css", "css")
var guide = document.getElementById("guideMenu")
guide.classList.remove("hidden");
}
}
</script>