Files
openlayers/config/jsdoc/api/template/static/scripts/main.js
Maximilian Krög b613e8e77f Fix regex dot escape
2020-02-21 22:56:53 +01:00

205 lines
6.6 KiB
JavaScript

$(function () {
// Allow user configuration?
const allowRegex = true;
const minInputForFullText = 1;
function constructRegex(searchTerm, makeRe, allowRegex) {
try {
if (allowRegex) {
return makeRe(searchTerm);
}
} catch (e) {
}
// In case of invalid regexp fall back to non-regexp, but still allow . to match /
return makeRe(searchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/\\\./g, '[./]'));
}
function getWeightFunction(searchTerm, allowRegex) {
function makeRe(searchTerm) {
return {
begin: new RegExp('(?:[.~]|\\b)' + searchTerm, 'g'), // Also match . and ~ to demote double matches, in weight function
name: new RegExp('\\b' + searchTerm + '(?:[~.]|$)'), // Match until module end or name end
fullName: new RegExp('^' + searchTerm + '$')
}
}
const re = constructRegex(searchTerm, makeRe, allowRegex);
return function (matchedItem, beginOnly) {
// We could get smarter on the weight here
let weight = 0;
const name = matchedItem.data('name');
const match = name.match(re.begin);
if (match) {
// `ol/geom/Geometry` matches twice when searching 'geom', is weighted higher.
// but don't boost something like `ol/source/Vector~VectorSource` when searching for 'Vect'.
let matches = match.length;
if (matches > 1 && /[.~]/.test(match[matches - 1])) {
matches -= 1;
}
weight += matches * 10000;
if (!beginOnly) {
// Full match of the last part of the path is weighted even higher
// Complete match is weighted highest.
if (re.fullName.test(name)) {
weight += 10000000;
} else if (re.name.test(name)) {
weight += 1000000;
}
}
// If everything else is equal, prefer shorter names.
weight -= name.length;
}
return weight;
}
}
// sort function callback
var weightSorter = function (a, b) {
var aW = $(a).data('weight') || 0;
var bW = $(b).data('weight') || 0;
return bW - aW;
};
// Show an item related a current documentation automatically
const longname = $('.page-title').data('filename')
.replace(/\.[a-z]+$/, '')
.replace('module-', 'module:')
.replace(/_/g, '/')
.replace(/-/g, '~');
var $currentItem = $('.navigation .item[data-longname="' + longname + '"]:eq(0)');
if ($currentItem.length) {
$currentItem
.prependTo('.navigation .list')
.show()
.find('.member-list')
.show();
}
function doSearch(searchTerm) {
var $el = $('.navigation');
if (searchTerm.length > 1) {
searchTerm = searchTerm.toLowerCase();
const getSearchWeight = getWeightFunction(searchTerm, allowRegex);
const beginOnly = searchTerm.length < minInputForFullText;
const regexp = constructRegex(searchTerm, function (searchTerm) {
return new RegExp(searchTerm);
}, allowRegex);
$el.find('li, .member-list').hide();
$el.find('li').each(function (i, v) {
const $item = $(v);
const name = $item.data('name');
if (regexp.test(name)) {
const $classEntry = $item.closest('.item');
const $members = $item.closest('.member-list');
// Do the weight thing
const weight = getSearchWeight($classEntry, beginOnly);
$classEntry.data('weight', weight);
$item.show();
$members.show();
$classEntry.show();
}
});
$(".navigation ul.list li.item:visible")
.sort(weightSorter) // sort elements
.appendTo(".navigation ul.list"); // append again to the list
} else {
$currentItem.prependTo('.navigation .list');
$currentItem.find('.member-list, li').show();
$el.find('.item').show();
}
$el.find('.list').scrollTop(0);
}
const searchInput = $('#search').get(0);
// Skip searches when typing fast.
let key;
let start;
const brandNode = document.querySelector('.brand');
function queueSearch() {
if (!key) {
start = Date.now();
key = setTimeout(function () {
key = undefined;
const searchTerm = searchInput.value;
doSearch(searchTerm);
const time = Date.now() - start
brandNode.innerHTML = time + ' ms';
console.log(searchTerm + ':', time, 'ms');
start = undefined;
}, 0);
}
}
// Search Items
searchInput.addEventListener('input', queueSearch);
if (searchInput.value) {
doSearch(searchInput.value);
}
// Toggle when click an item element
$('.navigation').on('click', '.toggle', function (e) {
$(this).parent().parent().find('.member-list').toggle();
});
// Auto resizing on navigation
var _onResize = function () {
var height = $(window).height();
var $el = $('.navigation');
$el.height(height).find('.list').height(height - 133);
};
$(window).on('resize', _onResize);
_onResize();
var currentVersion = document.getElementById('package-version').innerHTML;
// warn about outdated version
var packageUrl = 'https://raw.githubusercontent.com/openlayers/openlayers.github.io/build/package.json';
fetch(packageUrl).then(function(response) {
return response.json();
}).then(function(json) {
var latestVersion = json.version;
document.getElementById('latest-version').innerHTML = latestVersion;
var url = window.location.href;
var branchSearch = url.match(/\/([^\/]*)\/apidoc\//);
var cookieText = 'dismissed=-' + latestVersion + '-';
var dismissed = document.cookie.indexOf(cookieText) != -1;
if (branchSearch && !dismissed && /^v[0-9\.]*$/.test(branchSearch[1]) && currentVersion != latestVersion) {
var link = url.replace(branchSearch[0], '/latest/apidoc/');
fetch(link, {method: 'head'}).then(function(response) {
var a = document.getElementById('latest-link');
a.href = response.status == 200 ? link : '../../latest/apidoc/';
});
var latestCheck = document.getElementById('latest-check');
latestCheck.style.display = '';
document.getElementById('latest-dismiss').onclick = function() {
latestCheck.style.display = 'none';
document.cookie = cookieText;
}
}
});
// create source code links to github
var srcLinks = $('div.tag-source');
srcLinks.each(function(i, el) {
var textParts = el.innerHTML.trim().split(', ');
var link = 'https://github.com/openlayers/openlayers/blob/v' + currentVersion + '/src/ol/' +
textParts[0];
el.innerHTML = '<a href="' + link + '">' + textParts[0] + '</a>, ' +
'<a href="' + link + textParts[1].replace('line ', '#L') + '">' +
textParts[1] + '</a>';
});
});