Skip to content

Commit d293849

Browse files
committed
Merge commit '2eeba73abadb0351521149b2df814cf69b28c9bb'
2 parents 614a8fb + 2eeba73 commit d293849

2 files changed

Lines changed: 96 additions & 7 deletions

File tree

template/css/style.css

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,57 @@ body {
690690
color: var(--bg-color);
691691
}
692692

693+
/* Make help / output text selectable and show text cursor */
694+
#output,
695+
#output * ,
696+
#output .output-block,
697+
#output .help-text,
698+
#output .command-echo,
699+
#output pre,
700+
#output code,
701+
#content-display,
702+
#content-display .content-body,
703+
#content-display .content-body * {
704+
-webkit-user-select: text !important;
705+
-moz-user-select: text !important;
706+
-ms-user-select: text !important;
707+
user-select: text !important;
708+
cursor: text !important;
709+
}
710+
711+
/* Keep interactive controls non-selectable to avoid accidental selection */
712+
.nav-btn,
713+
#theme-toggle,
714+
#theme-menu,
715+
.input-line,
716+
#command-input,
717+
.content-maximize-btn,
718+
.section-link,
719+
summary {
720+
-webkit-user-select: none !important;
721+
-moz-user-select: none !important;
722+
-ms-user-select: none !important;
723+
user-select: none !important;
724+
}
725+
726+
/* Make links in output/selectable content visually distinct and clickable */
727+
#output a,
728+
#content-display a,
729+
#output .help-text a {
730+
color: var(--link-color);
731+
text-decoration: underline;
732+
cursor: pointer !important;
733+
}
734+
735+
/* Ensure selection cursor remains text and selection allowed */
736+
#output, #content-display, #content-display .content-body {
737+
-webkit-user-select: text !important;
738+
-moz-user-select: text !important;
739+
-ms-user-select: text !important;
740+
user-select: text !important;
741+
cursor: text !important;
742+
}
743+
693744
/* Pulse animation for inactive input */
694745
@keyframes pulse {
695746
0%, 100% {

template/js/app.js

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ const sections = {};
3333
// Build available commands from config
3434
const availableCommands = ['home', ...config.sections.map(s => s.id), 'help', 'download', 'clear'];
3535

36+
// Helper: escapeHtml and conservative linkify for help text only
37+
function escapeHtml(str) {
38+
return String(str)
39+
.replace(/&/g, '&')
40+
.replace(/</g, '&lt;')
41+
.replace(/>/g, '&gt;')
42+
.replace(/"/g, '&quot;')
43+
.replace(/'/g, '&#39;');
44+
}
45+
46+
function linkify(text) {
47+
const escaped = escapeHtml(text);
48+
const withLinks = escaped.replace(/(https?:\/\/[^\s<]+)/g, '<a href="$1" target="_blank" rel="noopener noreferrer">$1</a>');
49+
return withLinks.replace(/\n/g, '<br>');
50+
}
51+
3652
// Generate welcome message with dynamic padding
3753
function generateWelcomeMessage() {
3854
const title = config.conference.title || 'Conference';
@@ -367,7 +383,7 @@ Contact: ${config.contact.email || 'N/A'}
367383
Website: ${config.contact.website || 'N/A'}
368384
${config.contact.repository ? `Code base: ${config.contact.repository}` : ''}
369385
`;
370-
printOutput(helpText, 'help-text');
386+
printHelpText(helpText);
371387
contentDisplay.innerHTML = '';
372388
contentDisplay.classList.add('hidden');
373389
}
@@ -503,6 +519,15 @@ function printOutput(text, className = '') {
503519
output.appendChild(outputDiv);
504520
}
505521

522+
// Print help (sanitized, linkified)
523+
function printHelpText(rawText) {
524+
const out = document.getElementById('output');
525+
const block = document.createElement('div');
526+
block.className = 'output-block help-text';
527+
block.innerHTML = linkify(rawText);
528+
out.appendChild(block);
529+
}
530+
506531
// Scroll to bottom
507532
function scrollToBottom() {
508533
setTimeout(() => {
@@ -551,14 +576,27 @@ window.addEventListener('hashchange', async () => {
551576
}
552577
});
553578

554-
// Keep input focused
579+
// Keep input focused when clicking outside interactive areas, but don't steal focus/selection
555580
document.addEventListener('click', (e) => {
556-
if (!e.target.closest('#theme-menu') &&
557-
!e.target.closest('#theme-toggle') &&
558-
!e.target.closest('.top-nav') &&
559-
!e.target.closest('#content-display')) {
560-
input.focus();
581+
// If user clicked inside theme controls, top nav, content display or output, don't force-focus input.
582+
if (e.target.closest('#theme-menu') ||
583+
e.target.closest('#theme-toggle') ||
584+
e.target.closest('.top-nav') ||
585+
e.target.closest('#content-display') ||
586+
e.target.closest('#output')) {
587+
return;
588+
}
589+
const cmd = document.getElementById('command-input');
590+
if (cmd) cmd.focus();
591+
});
592+
593+
// Defensive: do not focus input on mousedown (this would steal selection)
594+
document.addEventListener('mousedown', (e) => {
595+
if (e.target.closest('#content-display') || e.target.closest('#output')) {
596+
// allow native selection to proceed — do not change focus
597+
return;
561598
}
599+
// otherwise no-op here; click handler will focus on click
562600
});
563601

564602
// Make input more obvious - pulse animation

0 commit comments

Comments
 (0)