356 lines
10 KiB
HTML
356 lines
10 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Mouse Support Test</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
max-width: 1200px;
|
|
margin: 20px auto;
|
|
padding: 0 20px;
|
|
}
|
|
|
|
.test-container {
|
|
border: 2px solid #333;
|
|
padding: 20px;
|
|
margin: 20px 0;
|
|
border-radius: 5px;
|
|
}
|
|
|
|
.test-element {
|
|
background-color: #f0f0f0;
|
|
border: 2px solid #999;
|
|
padding: 30px;
|
|
text-align: center;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
margin: 10px 0;
|
|
user-select: none;
|
|
}
|
|
|
|
.test-element:hover {
|
|
background-color: #e0e0e0;
|
|
}
|
|
|
|
.test-element:focus {
|
|
background-color: #e3f2fd;
|
|
border-color: #2196F3;
|
|
outline: none;
|
|
}
|
|
|
|
.log-container {
|
|
background-color: #1e1e1e;
|
|
color: #d4d4d4;
|
|
padding: 15px;
|
|
border-radius: 5px;
|
|
max-height: 400px;
|
|
overflow-y: auto;
|
|
font-family: 'Courier New', monospace;
|
|
font-size: 14px;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.log-entry {
|
|
margin: 5px 0;
|
|
padding: 5px;
|
|
border-left: 3px solid #4CAF50;
|
|
padding-left: 10px;
|
|
}
|
|
|
|
.log-entry.focus {
|
|
border-left-color: #2196F3;
|
|
}
|
|
|
|
.log-entry.no-focus {
|
|
border-left-color: #FF9800;
|
|
}
|
|
|
|
.actions-list {
|
|
background-color: #fff3cd;
|
|
border: 1px solid #ffc107;
|
|
padding: 15px;
|
|
border-radius: 5px;
|
|
margin: 10px 0;
|
|
}
|
|
|
|
.actions-list h3 {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.actions-list ul {
|
|
margin: 10px 0;
|
|
padding-left: 20px;
|
|
}
|
|
|
|
.actions-list code {
|
|
background-color: #f5f5f5;
|
|
padding: 2px 6px;
|
|
border-radius: 3px;
|
|
font-family: 'Courier New', monospace;
|
|
}
|
|
|
|
.clear-button {
|
|
background-color: #f44336;
|
|
color: white;
|
|
border: none;
|
|
padding: 10px 20px;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.clear-button:hover {
|
|
background-color: #d32f2f;
|
|
}
|
|
|
|
.remove-button {
|
|
background-color: #FF5722;
|
|
color: white;
|
|
border: none;
|
|
padding: 10px 20px;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
.remove-button:hover {
|
|
background-color: #E64A19;
|
|
}
|
|
|
|
.remove-button:disabled {
|
|
background-color: #ccc;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
h1, h2 {
|
|
color: #333;
|
|
}
|
|
|
|
.note {
|
|
background-color: #e3f2fd;
|
|
border-left: 4px solid #2196F3;
|
|
padding: 10px 15px;
|
|
margin: 10px 0;
|
|
border-radius: 3px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Mouse Support Test Page</h1>
|
|
|
|
<div class="actions-list">
|
|
<h3>🖱️ Configured Mouse Actions</h3>
|
|
<p><strong>Element 1 - All Actions:</strong></p>
|
|
<ul>
|
|
<li><code>click</code> - Simple left click</li>
|
|
<li><code>right_click</code> - Right click (context menu blocked)</li>
|
|
<li><code>ctrl+click</code> - Ctrl/Cmd + Click</li>
|
|
<li><code>shift+click</code> - Shift + Click</li>
|
|
<li><code>ctrl+shift+click</code> - Ctrl + Shift + Click</li>
|
|
<li><code>click right_click</code> - Click then right-click within 500ms</li>
|
|
<li><code>click click</code> - Click twice in sequence</li>
|
|
</ul>
|
|
<p><strong>Element 2 - Using rclick alias:</strong></p>
|
|
<ul>
|
|
<li><code>click</code> - Simple click</li>
|
|
<li><code>rclick</code> - Right click (using rclick alias)</li>
|
|
<li><code>click rclick</code> - Click then right-click sequence (using alias)</li>
|
|
</ul>
|
|
<p><strong>Note:</strong> <code>rclick</code> is an alias for <code>right_click</code> and works identically.</p>
|
|
<p><strong>Tip:</strong> Try different click combinations! Right-click menu will be blocked on test elements.</p>
|
|
</div>
|
|
|
|
<div class="note">
|
|
<strong>Click Behavior:</strong> The <code>click</code> action is detected GLOBALLY (anywhere on the page).
|
|
Try clicking outside the test elements - the click action will still trigger! The <code>is_inside</code>
|
|
parameter tells you if the click was inside or outside the element (perfect for "close popup if clicked outside" logic).
|
|
</div>
|
|
|
|
<div class="note">
|
|
<strong>Right-Click Behavior:</strong> The <code>right_click</code> action is detected ONLY when clicking ON the element.
|
|
Try right-clicking outside the test elements - the browser's context menu will appear normally.
|
|
</div>
|
|
|
|
<div class="note">
|
|
<strong>Mac Users:</strong> Use Cmd (⌘) instead of Ctrl. The library handles cross-platform compatibility automatically.
|
|
</div>
|
|
|
|
<div class="test-container">
|
|
<h2>Test Element 1 (All Actions)</h2>
|
|
<div id="test-element-1" class="test-element" tabindex="0">
|
|
Try different mouse actions here!<br>
|
|
Click, Right-click, Ctrl+Click, Shift+Click, sequences...
|
|
</div>
|
|
</div>
|
|
|
|
<div class="test-container">
|
|
<h2>Test Element 2 (Using rclick alias)</h2>
|
|
<div id="test-element-2" class="test-element" tabindex="0">
|
|
This element uses "rclick" alias for right-click<br>
|
|
Also has a "click rclick" sequence
|
|
</div>
|
|
<button class="remove-button" onclick="removeElement2()">
|
|
Remove Element 2 Mouse Support
|
|
</button>
|
|
</div>
|
|
|
|
<div class="test-container">
|
|
<h2>Test Input (normal clicking should work here)</h2>
|
|
<input type="text" placeholder="Try clicking, right-clicking here - should work normally"
|
|
style="width: 100%; padding: 10px; font-size: 14px;">
|
|
</div>
|
|
|
|
<div class="test-container" style="background-color: #f9f9f9;">
|
|
<h2>🎯 Click Outside Test Area</h2>
|
|
<p>Click anywhere in this gray area (outside the test elements above) to see that <code>click</code> is detected globally!</p>
|
|
<p style="margin-top: 20px; padding: 30px; background-color: white; border: 2px dashed #999; border-radius: 5px; text-align: center;">
|
|
This is just empty space - but clicking here will still trigger the registered <code>click</code> actions!
|
|
</p>
|
|
</div>
|
|
|
|
<div class="test-container">
|
|
<h2>Event Log</h2>
|
|
<button class="clear-button" onclick="clearLog()">Clear Log</button>
|
|
<div id="log" class="log-container"></div>
|
|
</div>
|
|
|
|
<!-- Include htmx -->
|
|
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
|
|
|
|
<!-- Mock htmx.ajax for testing -->
|
|
<script>
|
|
// Store original htmx.ajax if it exists
|
|
const originalHtmxAjax = window.htmx && window.htmx.ajax;
|
|
|
|
// Override htmx.ajax for testing purposes
|
|
if (window.htmx) {
|
|
window.htmx.ajax = function(method, url, config) {
|
|
const timestamp = new Date().toLocaleTimeString();
|
|
const hasFocus = config.values.has_focus;
|
|
const isInside = config.values.is_inside;
|
|
const combination = config.values.combination;
|
|
|
|
// Build details string with all config options
|
|
const details = [
|
|
`Combination: "${combination}"`,
|
|
`Element has focus: ${hasFocus}`,
|
|
`Click inside element: ${isInside}`
|
|
];
|
|
|
|
if (config.target) {
|
|
details.push(`Target: ${config.target}`);
|
|
}
|
|
if (config.swap) {
|
|
details.push(`Swap: ${config.swap}`);
|
|
}
|
|
if (config.values) {
|
|
const extraVals = Object.keys(config.values).filter(k => k !== 'combination' && k !== 'has_focus' && k !== 'is_inside');
|
|
if (extraVals.length > 0) {
|
|
details.push(`Extra values: ${JSON.stringify(extraVals.reduce((obj, k) => ({...obj, [k]: config.values[k]}), {}))}`);
|
|
}
|
|
}
|
|
|
|
logEvent(
|
|
`[${timestamp}] ${method} ${url}`,
|
|
...details,
|
|
hasFocus
|
|
);
|
|
|
|
// Uncomment below to use real htmx.ajax if you have a backend
|
|
// if (originalHtmxAjax) {
|
|
// originalHtmxAjax.call(this, method, url, config);
|
|
// }
|
|
};
|
|
}
|
|
|
|
function logEvent(title, ...details) {
|
|
const log = document.getElementById('log');
|
|
const hasFocus = details[details.length - 1];
|
|
|
|
const entry = document.createElement('div');
|
|
entry.className = `log-entry ${hasFocus ? 'focus' : 'no-focus'}`;
|
|
entry.innerHTML = `
|
|
<strong>${title}</strong><br>
|
|
${details.slice(0, -1).join('<br>')}
|
|
`;
|
|
|
|
log.insertBefore(entry, log.firstChild);
|
|
}
|
|
|
|
function clearLog() {
|
|
document.getElementById('log').innerHTML = '';
|
|
}
|
|
|
|
function removeElement2() {
|
|
remove_mouse_support('test-element-2');
|
|
logEvent('Element 2 mouse support removed',
|
|
'Click and right-click no longer trigger for Element 2',
|
|
'Element 1 still active', false);
|
|
// Disable the button
|
|
event.target.disabled = true;
|
|
event.target.textContent = 'Mouse Support Removed';
|
|
}
|
|
</script>
|
|
|
|
<!-- Include mouse support script -->
|
|
<script src="mouse_support.js"></script>
|
|
|
|
<!-- Initialize mouse support -->
|
|
<script>
|
|
// Element 1 - Full configuration
|
|
const combinations1 = {
|
|
"click": {
|
|
"hx-post": "/test/click"
|
|
},
|
|
"right_click": {
|
|
"hx-post": "/test/right-click"
|
|
},
|
|
"ctrl+click": {
|
|
"hx-post": "/test/ctrl-click",
|
|
"hx-swap": "innerHTML"
|
|
},
|
|
"shift+click": {
|
|
"hx-post": "/test/shift-click",
|
|
"hx-target": "#result"
|
|
},
|
|
"ctrl+shift+click": {
|
|
"hx-post": "/test/ctrl-shift-click",
|
|
"hx-vals": {"modifier": "both"}
|
|
},
|
|
"click right_click": {
|
|
"hx-post": "/test/click-then-right-click",
|
|
"hx-vals": {"type": "sequence"}
|
|
},
|
|
"click click": {
|
|
"hx-post": "/test/double-click-sequence"
|
|
}
|
|
};
|
|
|
|
add_mouse_support('test-element-1', JSON.stringify(combinations1));
|
|
|
|
// Element 2 - Using rclick alias
|
|
const combinations2 = {
|
|
"click": {
|
|
"hx-post": "/test/element2-click"
|
|
},
|
|
"rclick": { // Using rclick alias instead of right_click
|
|
"hx-post": "/test/element2-rclick"
|
|
},
|
|
"click rclick": { // Sequence using rclick alias
|
|
"hx-post": "/test/element2-click-rclick-sequence"
|
|
}
|
|
};
|
|
|
|
add_mouse_support('test-element-2', JSON.stringify(combinations2));
|
|
|
|
// Log initial state
|
|
logEvent('Mouse support initialized',
|
|
'Element 1: All mouse actions configured',
|
|
'Element 2: Using "rclick" alias (click, rclick, and click rclick sequence)',
|
|
'Smart timeout: 500ms for sequences', false);
|
|
</script>
|
|
</body>
|
|
</html> |