mirror of
https://github.com/InsanusMokrassar/KSLog.git
synced 2025-10-29 02:20:04 +00:00
deploy: 4528918347
This commit is contained in:
@@ -1,6 +1,35 @@
|
||||
/*
|
||||
* Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
|
||||
* Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
|
||||
*/
|
||||
/** When Dokka is viewed via iframe, local storage could be inaccessible (see https://github.com/Kotlin/dokka/issues/3323)
|
||||
* This is a wrapper around local storage to prevent errors in such cases
|
||||
* */
|
||||
const safeLocalStorage = (() => {
|
||||
let isLocalStorageAvailable = false;
|
||||
try {
|
||||
const testKey = '__testLocalStorageKey__';
|
||||
localStorage.setItem(testKey, testKey);
|
||||
localStorage.removeItem(testKey);
|
||||
isLocalStorageAvailable = true;
|
||||
} catch (e) {
|
||||
console.error('Local storage is not available', e);
|
||||
}
|
||||
|
||||
return {
|
||||
getItem: (key) => {
|
||||
if (!isLocalStorageAvailable) {
|
||||
return null;
|
||||
}
|
||||
return localStorage.getItem(key);
|
||||
},
|
||||
setItem: (key, value) => {
|
||||
if (!isLocalStorageAvailable) {
|
||||
return;
|
||||
}
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
filteringContext = {
|
||||
dependencies: {},
|
||||
@@ -23,16 +52,17 @@ window.addEventListener('load', () => {
|
||||
filterSection.addEventListener('click', (event) => filterButtonHandler(event))
|
||||
initializeFiltering()
|
||||
}
|
||||
initTabs()
|
||||
if (typeof initTabs === 'function') {
|
||||
initTabs() // initTabs comes from ui-kit/tabs
|
||||
}
|
||||
handleAnchor()
|
||||
initHidingLeftNavigation()
|
||||
topNavbarOffset = document.getElementById('navigation-wrapper')
|
||||
darkModeSwitch()
|
||||
})
|
||||
|
||||
const darkModeSwitch = () => {
|
||||
const localStorageKey = "dokka-dark-mode"
|
||||
const storage = localStorage.getItem(localStorageKey)
|
||||
const storage = safeLocalStorage.getItem(localStorageKey)
|
||||
const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
const darkModeEnabled = storage ? JSON.parse(storage) : osDarkSchemePreferred
|
||||
const element = document.getElementById("theme-toggle-button")
|
||||
@@ -49,7 +79,7 @@ const darkModeSwitch = () => {
|
||||
} else {
|
||||
initPlayground(samplesLightThemeName)
|
||||
}
|
||||
localStorage.setItem(localStorageKey, JSON.stringify(darkModeEnabled))
|
||||
safeLocalStorage.setItem(localStorageKey, JSON.stringify(darkModeEnabled))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -75,28 +105,17 @@ const initPlayground = (theme) => {
|
||||
// As an alternative we could extract this samples-specific script to new js file but then we would handle dark mode in 2 separate files which is not ideal
|
||||
const samplesAreEnabled = () => {
|
||||
try {
|
||||
KotlinPlayground
|
||||
return true
|
||||
if (typeof KotlinPlayground === 'undefined') {
|
||||
// KotlinPlayground is exported universally as a global variable or as a module
|
||||
// Due to possible interaction with other js scripts KotlinPlayground may not be accessible directly from `window`, so we need an additional check
|
||||
KotlinPlayground = exports.KotlinPlayground;
|
||||
}
|
||||
return typeof KotlinPlayground === 'function';
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const initHidingLeftNavigation = () => {
|
||||
document.getElementById("menu-toggle").onclick = function (event) {
|
||||
//Events need to be prevented from bubbling since they will trigger next handler
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.stopImmediatePropagation();
|
||||
document.getElementById("leftColumn").classList.toggle("open");
|
||||
}
|
||||
|
||||
document.getElementById("main").onclick = () => {
|
||||
document.getElementById("leftColumn").classList.remove("open");
|
||||
}
|
||||
}
|
||||
|
||||
// Hash change is needed in order to allow for linking inside the same page with anchors
|
||||
// If this is not present user is forced to refresh the site in order to use an anchor
|
||||
window.onhashchange = handleAnchor
|
||||
@@ -150,17 +169,17 @@ function handleAnchor() {
|
||||
}
|
||||
|
||||
let anchor = window.location.hash
|
||||
if (anchor != "") {
|
||||
if (anchor !== "") {
|
||||
anchor = anchor.substring(1)
|
||||
let element = document.querySelector('a[data-name="' + anchor + '"]')
|
||||
|
||||
if (element) {
|
||||
const content = element.nextElementSibling
|
||||
const contentStyle = window.getComputedStyle(content)
|
||||
if(contentStyle.display == 'none') {
|
||||
if(contentStyle.display === 'none') {
|
||||
let tab = findAnyTab(searchForContentTarget(content))
|
||||
if (tab) {
|
||||
toggleSections(tab)
|
||||
toggleSections(tab) // toggleSections comes from ui-kit/tabs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,44 +193,10 @@ function handleAnchor() {
|
||||
}
|
||||
}
|
||||
|
||||
function initTabs() {
|
||||
// we could have only a single type of data - classlike or package
|
||||
const mainContent = document.querySelector('.main-content');
|
||||
const type = mainContent ? mainContent.getAttribute("data-page-type") : null;
|
||||
const localStorageKey = "active-tab-" + type;
|
||||
document.querySelectorAll('div[tabs-section]').forEach(element => {
|
||||
showCorrespondingTabBody(element);
|
||||
element.addEventListener('click', ({target}) => {
|
||||
const togglable = target ? target.getAttribute("data-togglable") : null;
|
||||
if (!togglable) return;
|
||||
|
||||
localStorage.setItem(localStorageKey, JSON.stringify(togglable));
|
||||
toggleSections(target);
|
||||
});
|
||||
});
|
||||
|
||||
const cached = localStorage.getItem(localStorageKey);
|
||||
if (!cached) return;
|
||||
|
||||
const tab = document.querySelector(
|
||||
'div[tabs-section] > button[data-togglable="' + JSON.parse(cached) + '"]'
|
||||
);
|
||||
if (!tab) return;
|
||||
|
||||
toggleSections(tab);
|
||||
}
|
||||
|
||||
function showCorrespondingTabBody(element) {
|
||||
const buttonWithKey = element.querySelector("button[data-active]")
|
||||
if (buttonWithKey) {
|
||||
toggleSections(buttonWithKey)
|
||||
}
|
||||
}
|
||||
|
||||
function filterButtonHandler(event) {
|
||||
if (event.target.tagName == "BUTTON" && event.target.hasAttribute("data-filter")) {
|
||||
if (event.target.tagName === "BUTTON" && event.target.hasAttribute("data-filter")) {
|
||||
let sourceset = event.target.getAttribute("data-filter")
|
||||
if (filteringContext.activeFilters.indexOf(sourceset) != -1) {
|
||||
if (filteringContext.activeFilters.indexOf(sourceset) !== -1) {
|
||||
filterSourceset(sourceset)
|
||||
} else {
|
||||
unfilterSourceset(sourceset)
|
||||
@@ -227,11 +212,11 @@ function initializeFiltering() {
|
||||
filteringContext.dependencies[p] = filteringContext.dependencies[p]
|
||||
.filter(q => -1 !== filteringContext.restrictedDependencies.indexOf(q))
|
||||
})
|
||||
let cached = window.localStorage.getItem('inactive-filters')
|
||||
let cached = safeLocalStorage.getItem('inactive-filters')
|
||||
if (cached) {
|
||||
let parsed = JSON.parse(cached)
|
||||
filteringContext.activeFilters = filteringContext.restrictedDependencies
|
||||
.filter(q => parsed.indexOf(q) == -1)
|
||||
.filter(q => parsed.indexOf(q) === -1)
|
||||
} else {
|
||||
filteringContext.activeFilters = filteringContext.restrictedDependencies
|
||||
}
|
||||
@@ -239,13 +224,13 @@ function initializeFiltering() {
|
||||
}
|
||||
|
||||
function filterSourceset(sourceset) {
|
||||
filteringContext.activeFilters = filteringContext.activeFilters.filter(p => p != sourceset)
|
||||
filteringContext.activeFilters = filteringContext.activeFilters.filter(p => p !== sourceset)
|
||||
refreshFiltering()
|
||||
addSourcesetFilterToCache(sourceset)
|
||||
}
|
||||
|
||||
function unfilterSourceset(sourceset) {
|
||||
if (filteringContext.activeFilters.length == 0) {
|
||||
if (filteringContext.activeFilters.length === 0) {
|
||||
filteringContext.activeFilters = filteringContext.dependencies[sourceset].concat([sourceset])
|
||||
refreshFiltering()
|
||||
filteringContext.dependencies[sourceset].concat([sourceset]).forEach(p => removeSourcesetFilterFromCache(p))
|
||||
@@ -258,65 +243,43 @@ function unfilterSourceset(sourceset) {
|
||||
}
|
||||
|
||||
function addSourcesetFilterToCache(sourceset) {
|
||||
let cached = localStorage.getItem('inactive-filters')
|
||||
let cached = safeLocalStorage.getItem('inactive-filters')
|
||||
if (cached) {
|
||||
let parsed = JSON.parse(cached)
|
||||
localStorage.setItem('inactive-filters', JSON.stringify(parsed.concat([sourceset])))
|
||||
safeLocalStorage.setItem('inactive-filters', JSON.stringify(parsed.concat([sourceset])))
|
||||
} else {
|
||||
localStorage.setItem('inactive-filters', JSON.stringify([sourceset]))
|
||||
safeLocalStorage.setItem('inactive-filters', JSON.stringify([sourceset]))
|
||||
}
|
||||
}
|
||||
|
||||
function removeSourcesetFilterFromCache(sourceset) {
|
||||
let cached = localStorage.getItem('inactive-filters')
|
||||
let cached = safeLocalStorage.getItem('inactive-filters')
|
||||
if (cached) {
|
||||
let parsed = JSON.parse(cached)
|
||||
localStorage.setItem('inactive-filters', JSON.stringify(parsed.filter(p => p != sourceset)))
|
||||
safeLocalStorage.setItem('inactive-filters', JSON.stringify(parsed.filter(p => p !== sourceset)))
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSections(target) {
|
||||
const activateTabs = (containerClass) => {
|
||||
for (const element of document.getElementsByClassName(containerClass)) {
|
||||
for (const child of element.children) {
|
||||
if (child.getAttribute("data-togglable") === target.getAttribute("data-togglable")) {
|
||||
child.setAttribute("data-active", "")
|
||||
} else {
|
||||
child.removeAttribute("data-active")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const toggleTargets = target.getAttribute("data-togglable").split(",")
|
||||
const activateTabsBody = (containerClass) => {
|
||||
document.querySelectorAll("." + containerClass + " *[data-togglable]")
|
||||
.forEach(child => {
|
||||
if (toggleTargets.includes(child.getAttribute("data-togglable"))) {
|
||||
child.setAttribute("data-active", "")
|
||||
} else if(!child.classList.contains("sourceset-dependent-content")) { // data-togglable is used to switch source set as well, ignore it
|
||||
child.removeAttribute("data-active")
|
||||
}
|
||||
})
|
||||
}
|
||||
activateTabs("tabs-section")
|
||||
activateTabsBody("tabs-section-body")
|
||||
function refreshSourcesetsCache() {
|
||||
safeLocalStorage.setItem('inactive-filters', JSON.stringify(filteringContext.restrictedDependencies.filter(p => -1 === filteringContext.activeFilters.indexOf(p))))
|
||||
}
|
||||
|
||||
|
||||
function togglePlatformDependent(e, container) {
|
||||
let target = e.target
|
||||
if (target.tagName != 'BUTTON') return;
|
||||
if (target.tagName !== 'BUTTON') return;
|
||||
let index = target.getAttribute('data-toggle')
|
||||
|
||||
for (let child of container.children) {
|
||||
if (child.hasAttribute('data-toggle-list')) {
|
||||
for (let bm of child.children) {
|
||||
if (bm == target) {
|
||||
if (bm === target) {
|
||||
bm.setAttribute('data-active', "")
|
||||
} else if (bm != target) {
|
||||
} else if (bm !== target) {
|
||||
bm.removeAttribute('data-active')
|
||||
}
|
||||
}
|
||||
} else if (child.getAttribute('data-togglable') == index) {
|
||||
} else if (child.getAttribute('data-togglable') === index) {
|
||||
child.setAttribute('data-active', "")
|
||||
} else {
|
||||
child.removeAttribute('data-active')
|
||||
@@ -350,14 +313,18 @@ function refreshPlaygroundSamples() {
|
||||
|
||||
function refreshNoContentNotification() {
|
||||
const element = document.getElementsByClassName("main-content")[0]
|
||||
const filteredMessage = document.querySelector(".filtered-message")
|
||||
|
||||
if(filteringContext.activeFilters.length === 0){
|
||||
element.style.display = "none";
|
||||
|
||||
const appended = document.createElement("div")
|
||||
appended.className = "filtered-message"
|
||||
appended.innerText = "All documentation is filtered, please adjust your source set filters in top-right corner of the screen"
|
||||
sourcesetNotification = appended
|
||||
element.parentNode.prepend(appended)
|
||||
if (!filteredMessage) {
|
||||
const appended = document.createElement("div")
|
||||
appended.className = "filtered-message"
|
||||
appended.innerText = "All documentation is filtered, please adjust your source set filters in top-right corner of the screen"
|
||||
sourcesetNotification = appended
|
||||
element.parentNode.prepend(appended)
|
||||
}
|
||||
} else {
|
||||
if(sourcesetNotification) sourcesetNotification.remove()
|
||||
element.style.display = "block"
|
||||
@@ -371,8 +338,8 @@ function refreshPlatformTabs() {
|
||||
let firstAvailable = null
|
||||
p.childNodes.forEach(
|
||||
element => {
|
||||
if (element.getAttribute("data-filterable-current") != '') {
|
||||
if (firstAvailable == null) {
|
||||
if (element.getAttribute("data-filterable-current") !== '') {
|
||||
if (firstAvailable === null) {
|
||||
firstAvailable = element
|
||||
}
|
||||
if (element.hasAttribute("data-active")) {
|
||||
@@ -381,7 +348,7 @@ function refreshPlatformTabs() {
|
||||
}
|
||||
}
|
||||
)
|
||||
if (active == false && firstAvailable) {
|
||||
if (active === false && firstAvailable) {
|
||||
firstAvailable.click()
|
||||
}
|
||||
}
|
||||
@@ -391,10 +358,14 @@ function refreshPlatformTabs() {
|
||||
function refreshFilterButtons() {
|
||||
document.querySelectorAll("#filter-section > button")
|
||||
.forEach(f => {
|
||||
if (filteringContext.activeFilters.indexOf(f.getAttribute("data-filter")) != -1) {
|
||||
if (filteringContext.activeFilters.indexOf(f.getAttribute("data-filter")) !== -1) {
|
||||
f.setAttribute("data-active", "")
|
||||
} else {
|
||||
f.removeAttribute("data-active")
|
||||
}
|
||||
})
|
||||
document.querySelectorAll("#filter-section .checkbox--input")
|
||||
.forEach(f => {
|
||||
f.checked = filteringContext.activeFilters.indexOf(f.getAttribute("data-filter")) !== -1;
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user