|
|
|
@ -1,16 +1,52 @@
|
|
|
|
|
var headingList = [];
|
|
|
|
|
var scrollBehaviorAvaliable = (function() {
|
|
|
|
|
// 检测Chrome
|
|
|
|
|
var v = navigator.userAgent.match(/Chrome\/(?<version>\S+)/);
|
|
|
|
|
if (v && v.groups.version) { // 检测chrome版本
|
|
|
|
|
if (v && v.groups.version) {
|
|
|
|
|
var chromeVersion = parseInt(v.groups.version);
|
|
|
|
|
return chromeVersion >= 61;
|
|
|
|
|
} else { // 非chrome
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检测Firefox
|
|
|
|
|
v = navigator.userAgent.match(/Firefox\/(?<version>\S+)/);
|
|
|
|
|
if (v && v.groups.version) {
|
|
|
|
|
var firefoxVersion = parseInt(v.groups.version);
|
|
|
|
|
return firefoxVersion >= 36;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检测Safari
|
|
|
|
|
v = navigator.userAgent.match(/Version\/(?<version>\S+)/);
|
|
|
|
|
if (v && v.groups.version) { // Safari
|
|
|
|
|
var safariVersion = parseFloat(v.groups.version);
|
|
|
|
|
return safariVersion >= 14;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
})();
|
|
|
|
|
var isMobileSafari = (function(){
|
|
|
|
|
v = navigator.userAgent.match(/Version\/(?<version>\S+) Mobile\/\S+/);
|
|
|
|
|
if (v && v.groups.version) { // Safari
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
})();
|
|
|
|
|
var menuHidden = false;
|
|
|
|
|
|
|
|
|
|
var menuItems = [
|
|
|
|
|
{
|
|
|
|
|
label: mw.msg('isekai-offcanvastoc-hide-menubutton'),
|
|
|
|
|
onClick: () => {
|
|
|
|
|
$('#iseai-offcanvas-btn').hide();
|
|
|
|
|
menuHidden = true;
|
|
|
|
|
mw.notify( mw.msg('isekai-offcanvastoc-menubutton-hide-success'));
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
function getScrollOffset() {
|
|
|
|
|
if (mw.config.get('skin') === 'timeless' && $(window).width() > 850) {
|
|
|
|
|
if (mw.config.get('skin') === 'timeless' && window.innerWidth > 850) {
|
|
|
|
|
return 60;
|
|
|
|
|
} else if (mw.config.get('skin') === 'minerva') {
|
|
|
|
|
return 60;
|
|
|
|
|
} else {
|
|
|
|
|
return 10;
|
|
|
|
@ -18,7 +54,9 @@ function getScrollOffset() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getAnchorOffset() {
|
|
|
|
|
if (mw.config.get('skin') === 'timeless' && $(window).width() > 850) {
|
|
|
|
|
if (mw.config.get('skin') === 'timeless' && window.innerWidth > 850) {
|
|
|
|
|
return 70;
|
|
|
|
|
} else if (mw.config.get('skin') === 'minerva') {
|
|
|
|
|
return 70;
|
|
|
|
|
} else {
|
|
|
|
|
return 20;
|
|
|
|
@ -26,8 +64,10 @@ function getAnchorOffset() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function scrollToAnchor(link) {
|
|
|
|
|
var target = $(link.replace(/\./g, '\\.'));
|
|
|
|
|
if (target.length > 0) {
|
|
|
|
|
var el = document.getElementById(link.replace(/^#/, ''));
|
|
|
|
|
if (el) {
|
|
|
|
|
var target = $(el);
|
|
|
|
|
|
|
|
|
|
function doScroll() {
|
|
|
|
|
var position = target.offset().top - getScrollOffset();
|
|
|
|
|
|
|
|
|
@ -103,7 +143,13 @@ function updateActive() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function openOffcanvas() {
|
|
|
|
|
$('#iseai-offcanvas-btn').show();
|
|
|
|
|
menuHidden = false;
|
|
|
|
|
|
|
|
|
|
let scrollbarWidth = getScrollbarWidth();
|
|
|
|
|
$('#isekai-offcanvas-cover').removeClass('hidden');
|
|
|
|
|
|
|
|
|
|
window.requestAnimationFrame(function() {
|
|
|
|
|
$('body').addClass(['toc-offcanvas-show', 'toc-offcanvas-open'])
|
|
|
|
|
.css('margin-right', scrollbarWidth);
|
|
|
|
|
$('#iseai-offcanvas-btn').css('margin-right', scrollbarWidth);
|
|
|
|
@ -117,18 +163,69 @@ function openOffcanvas() {
|
|
|
|
|
let targetY = Math.max(activedItem.eq(0).prop('offsetTop') - 50, 0);
|
|
|
|
|
$('#isekai-offcanvas-toc').scrollTop(targetY);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function closeOffcanvas() {
|
|
|
|
|
if ($('#iseai-offcanvas-contextmenu').length > 0) {
|
|
|
|
|
$('#iseai-offcanvas-contextmenu').remove();
|
|
|
|
|
$('#isekai-offcanvas-cover').addClass('hidden');
|
|
|
|
|
} else {
|
|
|
|
|
$('body').removeClass('toc-offcanvas-open');
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
$('body').removeClass('toc-offcanvas-show').css('margin-right', 0);
|
|
|
|
|
$('#isekai-offcanvas-cover').addClass('hidden');
|
|
|
|
|
$('#iseai-offcanvas-btn').css('margin-right', 0);
|
|
|
|
|
if (mw.config.get('skin') === 'timeless') {
|
|
|
|
|
$('#mw-header-container').css('padding-right', 0);
|
|
|
|
|
}
|
|
|
|
|
}, 260);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function openContextMenu(position) {
|
|
|
|
|
var menuContainer = document.createElement('div');
|
|
|
|
|
menuContainer.id = 'iseai-offcanvas-contextmenu';
|
|
|
|
|
menuContainer.className = 'oo-ui-toolGroup-tools oo-ui-popupToolGroup-tools oo-ui-listToolGroup-tools oo-ui-toolGroup-enabled-tools oo-ui-popupToolGroup-active-tools';
|
|
|
|
|
menuContainer.style.minWidth = 'unset';
|
|
|
|
|
// 设置弹出位置
|
|
|
|
|
menuContainer.style.position = 'fixed';
|
|
|
|
|
menuContainer.style.zIndex = 105;
|
|
|
|
|
menuContainer.style.right = position.x ? ($(window).width() - position.x) + 'px' : null;
|
|
|
|
|
menuContainer.style.bottom = position.y ? ($(window).height() - position.y) + 'px' : null;
|
|
|
|
|
|
|
|
|
|
function hideMenu() {
|
|
|
|
|
menuContainer.remove();
|
|
|
|
|
$('#isekai-offcanvas-cover').addClass('hidden');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
menuItems.forEach((menuItem) => {
|
|
|
|
|
var menuElem = document.createElement('span');
|
|
|
|
|
menuElem.className = 'oo-ui-widget oo-ui-widget-enabled oo-ui-tool';
|
|
|
|
|
|
|
|
|
|
var menuLink = document.createElement('a');
|
|
|
|
|
menuLink.className = 'oo-ui-tool-link';
|
|
|
|
|
menuLink.tabIndex = 0;
|
|
|
|
|
menuLink.role = 'button';
|
|
|
|
|
menuLink.addEventListener('click', function(e) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
menuItem.onClick();
|
|
|
|
|
hideMenu();
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var menuLabel = document.createElement('span');
|
|
|
|
|
menuLabel.className = 'oo-ui-tool-title';
|
|
|
|
|
menuLabel.innerText = menuItem.label;
|
|
|
|
|
|
|
|
|
|
menuLink.appendChild(menuLabel);
|
|
|
|
|
menuElem.appendChild(menuLink);
|
|
|
|
|
menuContainer.appendChild(menuElem);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$('#isekai-offcanvas-cover').removeClass('hidden');
|
|
|
|
|
document.body.appendChild(menuContainer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$(function() {
|
|
|
|
|
// 创建目录dom
|
|
|
|
@ -136,8 +233,8 @@ $(function() {
|
|
|
|
|
<div id="isekai-offcanvas-toc" class="toc-offcanvas">
|
|
|
|
|
<ul></ul>
|
|
|
|
|
</div>
|
|
|
|
|
<button role="button" id="iseai-offcanvas-btn" class="toc-offcanvas-btn" aria-label="Open float table of contents menu"></button>
|
|
|
|
|
<div id="isekai-offcanvas-cover" class="toc-offcanvas-cover"></div>
|
|
|
|
|
<a role="button" href="#" id="iseai-offcanvas-btn" class="toc-offcanvas-btn" aria-label="Open float table of contents menu"></a>
|
|
|
|
|
<div id="isekai-offcanvas-cover" class="toc-offcanvas-cover hidden"></div>
|
|
|
|
|
`);
|
|
|
|
|
var menuIcon = new OO.ui.IconWidget({ icon: 'menu' });
|
|
|
|
|
$('#iseai-offcanvas-btn').append(menuIcon.$element);
|
|
|
|
@ -207,11 +304,51 @@ $(function() {
|
|
|
|
|
closeOffcanvas();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$('#iseai-offcanvas-btn').on('click', function() {
|
|
|
|
|
$('#iseai-offcanvas-btn').on('click', function(e) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
|
|
updateActive();
|
|
|
|
|
openOffcanvas();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var btnElem = $('#iseai-offcanvas-btn')[0];
|
|
|
|
|
btnElem.addEventListener('contextmenu', function(e) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
|
|
if (e.clientX) {
|
|
|
|
|
openContextMenu({
|
|
|
|
|
x: e.clientX,
|
|
|
|
|
y: e.clientY
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
openContextMenu({
|
|
|
|
|
x: e.pageX - window.scrollX,
|
|
|
|
|
y: e.pageY - window.scrollY
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (isMobileSafari) {
|
|
|
|
|
// Safari下对长按的特殊处理
|
|
|
|
|
var longPressTimer;
|
|
|
|
|
|
|
|
|
|
btnElem.addEventListener('touchstart', function(e) {
|
|
|
|
|
longPressTimer = setTimeout(function() {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
openContextMenu({
|
|
|
|
|
x: e.pageX - window.scrollX,
|
|
|
|
|
y: e.pageY - window.scrollY
|
|
|
|
|
});
|
|
|
|
|
}, 200);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
btnElem.addEventListener('touchend', function(e) {
|
|
|
|
|
if (longPressTimer) {
|
|
|
|
|
clearInterval(longPressTimer);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$('#isekai-offcanvas-toc ul .list-item').on('click', function(e) {
|
|
|
|
|
// 点击链接
|
|
|
|
|
e.preventDefault();
|
|
|
|
@ -221,10 +358,16 @@ $(function() {
|
|
|
|
|
$('#isekai-offcanvas-toc ul .list-item').removeClass('active');
|
|
|
|
|
$(this).addClass('active');
|
|
|
|
|
scrollToAnchor(target);
|
|
|
|
|
if ($(window).width() < 550) { // 手机端,关闭抽屉
|
|
|
|
|
if (window.innerWidth < 550) { // 手机端,关闭抽屉
|
|
|
|
|
closeOffcanvas();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$('#content').on('dblclick', function(e) {
|
|
|
|
|
if (menuHidden || window._openOffcanvasTocViaDblclick) {
|
|
|
|
|
openOffcanvas();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|