MediaWiki:Common.js: Difference between revisions
m Fix global collapsible controls |
m Restore floating expand collapse controls |
||
| (4 intermediate revisions by the same user not shown) | |||
| Line 14: | Line 14: | ||
}); | }); | ||
(function () { | |||
window.muhroGetFloatingTools = function () { | |||
var $tools = $('#muhro-floating-tools'); | |||
if (!$tools.length) { | |||
$tools = $('<div>') | |||
.attr('id', 'muhro-floating-tools') | |||
.addClass('muhro-floating-tools noprint'); | |||
$('body').append($tools); | |||
} | |||
return $tools; | |||
}; | |||
}()); | |||
(function () { | (function () { | ||
function normalizeLegacyCollapsibles($root) { | function normalizeLegacyCollapsibles($root) { | ||
$root.find('table.collapsible, div.collapsible, ul.collapsible, ol.collapsible').each(function () { | var $legacy = $root.find('table.collapsible, div.collapsible, ul.collapsible, ol.collapsible') | ||
.not('.mw-collapsible'); | |||
$legacy.each(function () { | |||
var $element = $(this); | var $element = $(this); | ||
| Line 25: | Line 43: | ||
} | } | ||
}); | }); | ||
$ | $legacy.makeCollapsible(); | ||
} | } | ||
function findCollapsibles($root) { | function findCollapsibles($root) { | ||
return $root | return $root | ||
.find('.mw | .find('.mw-collapsible') | ||
.add($root.filter('.mw | .add($root.filter('.mw-collapsible')); | ||
} | } | ||
| Line 51: | Line 59: | ||
$expand.prop('disabled', $items.length === 0 || collapsedCount === 0); | $expand.prop('disabled', $items.length === 0 || collapsedCount === 0); | ||
$collapse.prop('disabled', $items.length === 0 || collapsedCount === $items.length); | $collapse.prop('disabled', $items.length === 0 || collapsedCount === $items.length); | ||
} | |||
function triggerFallback($element, collapse) { | |||
if ($element.hasClass('mw-collapsed') === collapse) { | |||
return; | |||
} | |||
$element.find('> .muhro-early-toggle, .muhro-early-toggle').first().trigger('click'); | |||
} | } | ||
| Line 58: | Line 74: | ||
var api = $element.data('mw-collapsible'); | var api = $element.data('mw-collapsible'); | ||
if ( | if ($element.hasClass('mw-collapsed') === collapse) { | ||
return; | return; | ||
} | } | ||
if (collapse) { | if (api) { | ||
api. | if (collapse) { | ||
api.collapse(); | |||
} else { | |||
api.expand(); | |||
} | |||
} else { | } else { | ||
triggerFallback($element, collapse); | |||
} | } | ||
}); | }); | ||
updateButtons($root, $expand, $collapse); | window.setTimeout(function () { | ||
updateButtons($root, $expand, $collapse); | |||
}, 0); | |||
} | } | ||
function | function attachControls($root) { | ||
if ($('#muhro-collapse-controls').length || !findCollapsibles($root).length) { | |||
return false; | |||
if ($('#muhro-collapse-controls').length || !$ | |||
return; | |||
} | } | ||
| Line 100: | Line 113: | ||
'aria-label': 'Collapsible content controls' | 'aria-label': 'Collapsible content controls' | ||
}) | }) | ||
.addClass('muhro-collapse-controls | .addClass('muhro-collapse-controls') | ||
.append($expand, $collapse); | .append($expand, $collapse); | ||
| Line 116: | Line 129: | ||
updateButtons($root, $expand, $collapse); | updateButtons($root, $expand, $collapse); | ||
$(' | window.muhroGetFloatingTools().prepend($controls); | ||
return true; | |||
} | |||
function addCollapsibleControls($content) { | |||
var $root = $content.find('.mw-parser-output').first(); | |||
var attempts = 0; | |||
if (!$root.length) { | |||
$root = $content; | |||
} | |||
normalizeLegacyCollapsibles($root); | |||
function tryAttach() { | |||
attempts++; | |||
if (attachControls($root) || attempts >= 40) { | |||
return; | |||
} | |||
window.setTimeout(tryAttach, 250); | |||
} | |||
tryAttach(); | |||
} | } | ||
| Line 122: | Line 157: | ||
mw.hook('wikipage.content').add(addCollapsibleControls); | mw.hook('wikipage.content').add(addCollapsibleControls); | ||
}); | }); | ||
}()); | |||
(function () { | |||
function filterToc($panel, query) { | |||
var normalized = query.trim().toLowerCase(); | |||
$panel.find('li').removeClass('muhro-toc-match muhro-toc-hidden muhro-toc-ancestor'); | |||
if (!normalized) { | |||
return; | |||
} | |||
$panel.find('li').each(function () { | |||
var $item = $(this); | |||
var text = $item.children('a').first().text().toLowerCase(); | |||
if (text.indexOf(normalized) !== -1) { | |||
$item.addClass('muhro-toc-match'); | |||
$item.parents('li').addClass('muhro-toc-ancestor'); | |||
} | |||
}); | |||
$panel.find('li').each(function () { | |||
var $item = $(this); | |||
if (!$item.hasClass('muhro-toc-match') && !$item.hasClass('muhro-toc-ancestor')) { | |||
$item.addClass('muhro-toc-hidden'); | |||
} | |||
}); | |||
} | |||
function addFloatingToc($content) { | |||
var $toc = $content.find('#toc').first(); | |||
var $tocList; | |||
var $button; | |||
var $panel; | |||
var $header; | |||
var $filter; | |||
var $body; | |||
var $wrapper; | |||
if ($('#muhro-floating-toc').length || !$toc.length) { | |||
return; | |||
} | |||
$tocList = $toc.find('> ul, .toc > ul').first().clone(false); | |||
if (!$tocList.length) { | |||
$tocList = $toc.find('ul').first().clone(false); | |||
} | |||
if (!$tocList.length) { | |||
return; | |||
} | |||
$tocList.find('[id]').removeAttr('id'); | |||
$tocList.find('.tocnumber').attr('aria-hidden', 'true'); | |||
$button = $('<button>') | |||
.attr({ | |||
type: 'button', | |||
'aria-expanded': 'false', | |||
'aria-controls': 'muhro-floating-toc-panel' | |||
}) | |||
.addClass('muhro-floating-toc-button') | |||
.text('Contents'); | |||
$filter = $('<input>') | |||
.attr({ | |||
type: 'search', | |||
placeholder: 'Filter contents', | |||
'aria-label': 'Filter contents' | |||
}) | |||
.addClass('muhro-floating-toc-filter'); | |||
$header = $('<div>') | |||
.addClass('muhro-floating-toc-header') | |||
.append($filter); | |||
$body = $('<div>') | |||
.addClass('muhro-floating-toc-body') | |||
.append($tocList); | |||
$panel = $('<nav>') | |||
.attr({ | |||
id: 'muhro-floating-toc-panel', | |||
'aria-label': 'Page contents' | |||
}) | |||
.addClass('muhro-floating-toc-panel') | |||
.append($header, $body); | |||
$wrapper = $('<div>') | |||
.attr('id', 'muhro-floating-toc') | |||
.addClass('muhro-floating-toc') | |||
.append($button, $panel); | |||
$button.on('click', function () { | |||
var open = !$wrapper.hasClass('is-open'); | |||
$wrapper.toggleClass('is-open', open); | |||
$button.attr('aria-expanded', open ? 'true' : 'false'); | |||
if (open) { | |||
window.setTimeout(function () { | |||
$filter.trigger('focus'); | |||
}, 0); | |||
} | |||
}); | |||
$filter.on('input', function () { | |||
filterToc($panel, $filter.val()); | |||
}); | |||
$panel.on('click', 'a', function () { | |||
if (window.matchMedia('(max-width: 720px)').matches) { | |||
$wrapper.removeClass('is-open'); | |||
$button.attr('aria-expanded', 'false'); | |||
} | |||
}); | |||
window.muhroGetFloatingTools().append($wrapper); | |||
} | |||
mw.hook('wikipage.content').add(addFloatingToc); | |||
}()); | }()); | ||