mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-08-04 04:57:05 -04:00
147 lines
4.5 KiB
JavaScript
147 lines
4.5 KiB
JavaScript
let headings = Array.from(document.querySelectorAll('h1, h2, h3, h4, h5, h6'))
|
|
|
|
// generate id for all headings if there isn't one already
|
|
headings.forEach( (heading, index) => {
|
|
if (!heading.id) {
|
|
let parts = heading.textContent.trim().split(' ').concat([index])
|
|
heading.id = parts.join('_')
|
|
}
|
|
})
|
|
|
|
// create observer
|
|
let observer = new IntersectionObserver(function(entries) {
|
|
for (index in entries) {
|
|
let entry = entries[index]
|
|
if (entry.isIntersecting === false && entry.boundingClientRect.top <= entry.rootBounds.top) {
|
|
window.webkit.messageHandlers.headingVisible.postMessage({id: entry.target.id})
|
|
return
|
|
} else if (
|
|
entry.isIntersecting === false &&
|
|
entry.boundingClientRect.bottom > entry.rootBounds.bottom
|
|
) {
|
|
let index = headings.findIndex(element => element.id == entry.target.id )
|
|
let previousHeading = headings[index - 1]
|
|
window.webkit.messageHandlers.headingVisible.postMessage({id: previousHeading.id})
|
|
console.log(previousHeading)
|
|
return
|
|
}
|
|
}
|
|
}, { rootMargin: '-50px 0 -35% 0', threshold: 1.0 });
|
|
|
|
// register scroll view to handle heading on top of the page
|
|
window.onscroll = function() {
|
|
if (document.documentElement.scrollTop <= 0) {
|
|
const headingVisible = window.webkit.messageHandlers.headingVisible
|
|
if(headingVisible !== undefined && headingVisible.postMessage !== undefined) {
|
|
headingVisible.postMessage({id: headings[0].id})
|
|
}
|
|
}
|
|
}
|
|
|
|
// expand all detail tags
|
|
function expandAllDetailTags() {
|
|
document.querySelectorAll('details').forEach( detail => detail.setAttribute('open', true) )
|
|
}
|
|
|
|
// convert all headings into objects and send it to app side
|
|
function getOutlineItems() {
|
|
window.webkit.messageHandlers.headings.postMessage(
|
|
headings.map( heading => {
|
|
return {
|
|
id: heading.id,
|
|
text: heading.textContent.trim(),
|
|
tag: heading.tagName,
|
|
}
|
|
})
|
|
)
|
|
}
|
|
|
|
// observe headings for intersection
|
|
function observeHeadings() {
|
|
observer.disconnect()
|
|
headings.forEach( heading => { observer.observe(heading) })
|
|
}
|
|
|
|
function scrollToHeading(id) {
|
|
element = document.getElementById(id)
|
|
element.scrollIntoView({block: 'start', inline: 'start', behavior: 'smooth'})
|
|
}
|
|
|
|
function pauseVideoWhenNotInPIP() {
|
|
// make sure it's not in picture in picture mode:
|
|
if (document.pictureInPictureElement != null) {
|
|
return;
|
|
}
|
|
document.querySelectorAll("video").forEach((video) => {
|
|
video.pause();
|
|
});
|
|
}
|
|
|
|
function refreshVideoState() {
|
|
// make sure it's not in picture in picture mode:
|
|
if (document.pictureInPictureElement != null) {
|
|
return;
|
|
}
|
|
|
|
document.querySelectorAll("video").forEach((video) => {
|
|
if (video.paused && video.currentTime > 0) {
|
|
video.play();
|
|
video.pause();
|
|
}
|
|
});
|
|
}
|
|
|
|
function disableVideoContextMenu() {
|
|
document.querySelectorAll("video").forEach((video) => {
|
|
video.addEventListener("contextmenu", function(e) { e.preventDefault(); }, false);
|
|
});
|
|
}
|
|
|
|
function fixVideoElements() {
|
|
|
|
function fixVideoAttributes(element) {
|
|
element.querySelectorAll("video").forEach((video) => {
|
|
const attributes = video.attributes
|
|
if(attributes.getNamedItem('poster')) {
|
|
attributes.removeNamedItem('poster');
|
|
}
|
|
video.setAttribute('playsinline', '');
|
|
});
|
|
}
|
|
|
|
// fix in the currently loaded DOM
|
|
fixVideoAttributes(document);
|
|
|
|
// observe the DOM, if video content is added, fix that as well
|
|
var observeDOM = (function() {
|
|
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
|
|
|
|
return function(obj, callback) {
|
|
if (!obj || obj.nodeType !== 1) {
|
|
return;
|
|
}
|
|
|
|
if (MutationObserver) {
|
|
// define a new observer
|
|
var mutationObserver = new MutationObserver(callback);
|
|
// have the observer observe for changes in children
|
|
mutationObserver.observe(obj, {attributes: false, childList: true, subtree: true});
|
|
return mutationObserver;
|
|
}
|
|
}
|
|
})();
|
|
|
|
// Observe the body DOM element:
|
|
observeDOM(document.querySelector('body'), function(mutationList) {
|
|
for (const mutation of mutationList) {
|
|
if (mutation.type === 'childList' & mutation.addedNodes.length) {
|
|
for (const addedNode of mutation.addedNodes) {
|
|
if(addedNode.querySelectorAll) {
|
|
fixVideoAttributes(addedNode);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|