"Ignore text" is now "Remove text", it works the same but it removes the text instead of ignoring it, which is the same thing, but makes the code simplerpull/2679/head
parent
dad9760832
commit
00458b95c4
@ -0,0 +1,120 @@
|
|||||||
|
(function($) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
$('#code-block').highlightLines([
|
||||||
|
{
|
||||||
|
'color': '#dd0000',
|
||||||
|
'lines': [10, 12]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'color': '#ee0000',
|
||||||
|
'lines': [15, 18]
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
$.fn.highlightLines = function(configurations) {
|
||||||
|
return this.each(function() {
|
||||||
|
const $pre = $(this);
|
||||||
|
const textContent = $pre.text();
|
||||||
|
const lines = textContent.split(/\r?\n/); // Handles both \n and \r\n line endings
|
||||||
|
|
||||||
|
// Build a map of line numbers to styles
|
||||||
|
const lineStyles = {};
|
||||||
|
|
||||||
|
configurations.forEach(config => {
|
||||||
|
const { color, lines: lineNumbers } = config;
|
||||||
|
lineNumbers.forEach(lineNumber => {
|
||||||
|
lineStyles[lineNumber] = color;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Function to escape HTML characters
|
||||||
|
function escapeHtml(text) {
|
||||||
|
return text.replace(/[&<>"'`=\/]/g, function(s) {
|
||||||
|
return "&#" + s.charCodeAt(0) + ";";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process each line
|
||||||
|
const processedLines = lines.map((line, index) => {
|
||||||
|
const lineNumber = index + 1; // Line numbers start at 1
|
||||||
|
const escapedLine = escapeHtml(line);
|
||||||
|
const color = lineStyles[lineNumber];
|
||||||
|
|
||||||
|
if (color) {
|
||||||
|
// Wrap the line in a span with inline style
|
||||||
|
return `<span style="background-color: ${color}">${escapedLine}</span>`;
|
||||||
|
} else {
|
||||||
|
return escapedLine;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Join the lines back together
|
||||||
|
const newContent = processedLines.join('\n');
|
||||||
|
|
||||||
|
// Set the new content as HTML
|
||||||
|
$pre.html(newContent);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
$.fn.miniTabs = function(tabsConfig, options) {
|
||||||
|
const settings = {
|
||||||
|
tabClass: 'minitab',
|
||||||
|
tabsContainerClass: 'minitabs',
|
||||||
|
activeClass: 'active',
|
||||||
|
...(options || {})
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.each(function() {
|
||||||
|
const $wrapper = $(this);
|
||||||
|
const $contents = $wrapper.find('div[id]').hide();
|
||||||
|
const $tabsContainer = $('<div>', { class: settings.tabsContainerClass }).prependTo($wrapper);
|
||||||
|
|
||||||
|
// Generate tabs
|
||||||
|
Object.entries(tabsConfig).forEach(([tabTitle, contentSelector], index) => {
|
||||||
|
const $content = $wrapper.find(contentSelector);
|
||||||
|
if (index === 0) $content.show(); // Show first content by default
|
||||||
|
|
||||||
|
$('<a>', {
|
||||||
|
class: `${settings.tabClass}${index === 0 ? ` ${settings.activeClass}` : ''}`,
|
||||||
|
text: tabTitle,
|
||||||
|
'data-target': contentSelector
|
||||||
|
}).appendTo($tabsContainer);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Tab click event
|
||||||
|
$tabsContainer.on('click', `.${settings.tabClass}`, function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const $tab = $(this);
|
||||||
|
const target = $tab.data('target');
|
||||||
|
|
||||||
|
// Update active tab
|
||||||
|
$tabsContainer.find(`.${settings.tabClass}`).removeClass(settings.activeClass);
|
||||||
|
$tab.addClass(settings.activeClass);
|
||||||
|
|
||||||
|
// Show/hide content
|
||||||
|
$contents.hide();
|
||||||
|
$wrapper.find(target).show();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Object to store ongoing requests by namespace
|
||||||
|
const requests = {};
|
||||||
|
|
||||||
|
$.abortiveSingularAjax = function(options) {
|
||||||
|
const namespace = options.namespace || 'default';
|
||||||
|
|
||||||
|
// Abort the current request in this namespace if it's still ongoing
|
||||||
|
if (requests[namespace]) {
|
||||||
|
requests[namespace].abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a new AJAX request and store its reference in the correct namespace
|
||||||
|
requests[namespace] = $.ajax(options);
|
||||||
|
|
||||||
|
// Return the current request in case it's needed
|
||||||
|
return requests[namespace];
|
||||||
|
};
|
||||||
|
})(jQuery);
|
@ -1,53 +1,63 @@
|
|||||||
function redirect_to_version(version) {
|
function redirectToVersion(version) {
|
||||||
var currentUrl = window.location.href;
|
var currentUrl = window.location.href.split('?')[0]; // Base URL without query parameters
|
||||||
var baseUrl = currentUrl.split('?')[0]; // Base URL without query parameters
|
|
||||||
var anchor = '';
|
var anchor = '';
|
||||||
|
|
||||||
// Check if there is an anchor
|
// Check if there is an anchor
|
||||||
if (baseUrl.indexOf('#') !== -1) {
|
if (currentUrl.indexOf('#') !== -1) {
|
||||||
anchor = baseUrl.substring(baseUrl.indexOf('#'));
|
anchor = currentUrl.substring(currentUrl.indexOf('#'));
|
||||||
baseUrl = baseUrl.substring(0, baseUrl.indexOf('#'));
|
currentUrl = currentUrl.substring(0, currentUrl.indexOf('#'));
|
||||||
}
|
}
|
||||||
window.location.href = baseUrl + '?version=' + version + anchor;
|
|
||||||
|
window.location.href = currentUrl + '?version=' + version + anchor;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('keydown', function (event) {
|
function setupDateWidget() {
|
||||||
var selectElement = document.getElementById('preview-version');
|
$(document).on('keydown', function (event) {
|
||||||
if (selectElement) {
|
var $selectElement = $('#preview-version');
|
||||||
var selectedOption = selectElement.querySelector('option:checked');
|
var $selectedOption = $selectElement.find('option:selected');
|
||||||
if (selectedOption) {
|
|
||||||
if (event.key === 'ArrowLeft') {
|
if ($selectedOption.length) {
|
||||||
if (selectedOption.previousElementSibling) {
|
if (event.key === 'ArrowLeft' && $selectedOption.prev().length) {
|
||||||
redirect_to_version(selectedOption.previousElementSibling.value);
|
redirectToVersion($selectedOption.prev().val());
|
||||||
}
|
} else if (event.key === 'ArrowRight' && $selectedOption.next().length) {
|
||||||
} else if (event.key === 'ArrowRight') {
|
redirectToVersion($selectedOption.next().val());
|
||||||
if (selectedOption.nextElementSibling) {
|
|
||||||
redirect_to_version(selectedOption.nextElementSibling.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#preview-version').on('change', function () {
|
||||||
|
redirectToVersion($(this).val());
|
||||||
|
});
|
||||||
|
|
||||||
document.getElementById('preview-version').addEventListener('change', function () {
|
var $selectedOption = $('#preview-version option:selected');
|
||||||
redirect_to_version(this.value);
|
|
||||||
});
|
if ($selectedOption.length) {
|
||||||
|
var $prevOption = $selectedOption.prev();
|
||||||
|
var $nextOption = $selectedOption.next();
|
||||||
|
|
||||||
var selectElement = document.getElementById('preview-version');
|
if ($prevOption.length) {
|
||||||
if (selectElement) {
|
$('#btn-previous').attr('href', '?version=' + $prevOption.val());
|
||||||
var selectedOption = selectElement.querySelector('option:checked');
|
|
||||||
if (selectedOption) {
|
|
||||||
if (selectedOption.previousElementSibling) {
|
|
||||||
document.getElementById('btn-previous').href = "?version=" + selectedOption.previousElementSibling.value;
|
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('btn-previous').remove()
|
$('#btn-previous').remove();
|
||||||
}
|
}
|
||||||
if (selectedOption.nextElementSibling) {
|
|
||||||
document.getElementById('btn-next').href = "?version=" + selectedOption.nextElementSibling.value;
|
if ($nextOption.length) {
|
||||||
|
$('#btn-next').attr('href', '?version=' + $nextOption.val());
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('btn-next').remove()
|
$('#btn-next').remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
if ($('#preview-version').length) {
|
||||||
|
setupDateWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#diff-col > pre').highlightLines([
|
||||||
|
{
|
||||||
|
'color': '#ee0000',
|
||||||
|
'lines': triggered_line_numbers
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
.minitabs-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
> div[id] {
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minitabs {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minitab {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 12px 0;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #333;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-bottom: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minitab:hover {
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minitab.active {
|
||||||
|
background-color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue