refactor: remove command palette JavaScript
This commit is contained in:
+2
-220
@@ -898,187 +898,14 @@ function _setViewingSession(name) {
|
|||||||
_viewingSession = name;
|
_viewingSession = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Command palette state ────────────────────────────────────────────────────
|
|
||||||
const PALETTE_MAX_ITEMS = 9;
|
|
||||||
let _paletteSelectedIndex = 0;
|
|
||||||
let _paletteFilteredSessions = [];
|
|
||||||
let _paletteOpen = false;
|
|
||||||
let _paletteInputListener = null;
|
|
||||||
|
|
||||||
// ─── Command palette functions ────────────────────────────────────────────────
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render the filtered session list inside #palette-list.
|
|
||||||
* Shows up to 9 items. Each item is a <li> with index number,
|
|
||||||
* session name, optional bell emoji, and timestamp.
|
|
||||||
*/
|
|
||||||
function renderPaletteList() {
|
|
||||||
const list = $('palette-list');
|
|
||||||
if (!list) return;
|
|
||||||
|
|
||||||
const items = _paletteFilteredSessions.slice(0, PALETTE_MAX_ITEMS);
|
|
||||||
list.innerHTML = items
|
|
||||||
.map((session, i) => {
|
|
||||||
const isBell = sessionPriority(session) === 'bell';
|
|
||||||
const bell = isBell ? ' 🔔' : '';
|
|
||||||
const time = formatTimestamp(session.last_activity_at || null);
|
|
||||||
const name = escapeHtml(session.name || '');
|
|
||||||
return `<li class="palette-item" data-index="${i}">${i + 1} ${name}${bell} ${escapeHtml(time)}</li>`;
|
|
||||||
})
|
|
||||||
.join('');
|
|
||||||
|
|
||||||
// Bind click handlers on each item
|
|
||||||
list.querySelectorAll('.palette-item').forEach((item) => {
|
|
||||||
on(item, 'click', () => {
|
|
||||||
const idx = parseInt(item.dataset.index, 10);
|
|
||||||
const session = _paletteFilteredSessions[idx];
|
|
||||||
if (session) {
|
|
||||||
closePalette();
|
|
||||||
openSession(session.name).catch((err) => console.error('[renderPaletteList]', err));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
highlightPaletteItem(_paletteSelectedIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggle the palette-item--selected class on the item at `index`.
|
|
||||||
* @param {number} index
|
|
||||||
*/
|
|
||||||
function highlightPaletteItem(index) {
|
|
||||||
const list = $('palette-list');
|
|
||||||
if (!list) return;
|
|
||||||
list.querySelectorAll('.palette-item').forEach((item, i) => {
|
|
||||||
if (i === index) {
|
|
||||||
item.classList.add('palette-item--selected');
|
|
||||||
} else {
|
|
||||||
item.classList.remove('palette-item--selected');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the command palette.
|
|
||||||
* Shows #command-palette, copies _currentSessions to _paletteFilteredSessions,
|
|
||||||
* renders the list, resets selection index, focuses #palette-input, and binds
|
|
||||||
* the input event listener.
|
|
||||||
*/
|
|
||||||
function openPalette() {
|
|
||||||
_paletteOpen = true;
|
|
||||||
_paletteFilteredSessions = _currentSessions.slice();
|
|
||||||
_paletteSelectedIndex = 0;
|
|
||||||
|
|
||||||
const palette = $('command-palette');
|
|
||||||
if (palette) palette.classList.remove('hidden'); // palette starts with hidden class
|
|
||||||
|
|
||||||
renderPaletteList();
|
|
||||||
|
|
||||||
const input = $('palette-input');
|
|
||||||
if (input) {
|
|
||||||
input.value = '';
|
|
||||||
input.focus();
|
|
||||||
if (_paletteInputListener) {
|
|
||||||
input.removeEventListener('input', _paletteInputListener);
|
|
||||||
}
|
|
||||||
_paletteInputListener = onPaletteInput;
|
|
||||||
input.addEventListener('input', _paletteInputListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the command palette.
|
|
||||||
* Hides #command-palette and removes the input event listener.
|
|
||||||
*/
|
|
||||||
function closePalette() {
|
|
||||||
_paletteOpen = false;
|
|
||||||
|
|
||||||
const palette = $('command-palette');
|
|
||||||
if (palette) palette.classList.add('hidden');
|
|
||||||
|
|
||||||
const input = $('palette-input');
|
|
||||||
if (input && _paletteInputListener) {
|
|
||||||
input.removeEventListener('input', _paletteInputListener);
|
|
||||||
_paletteInputListener = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle input events on #palette-input.
|
|
||||||
* Filters sessions by the current query, re-renders the list, resets selection.
|
|
||||||
* @param {Event} e
|
|
||||||
*/
|
|
||||||
function onPaletteInput(e) {
|
|
||||||
const query = e && e.target ? e.target.value : '';
|
|
||||||
_paletteFilteredSessions = filterByQuery(_currentSessions, query);
|
|
||||||
_paletteSelectedIndex = 0;
|
|
||||||
renderPaletteList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle keydown events inside the command palette.
|
|
||||||
* ArrowDown/Up moves selection, Enter opens selected session,
|
|
||||||
* Escape closes palette, G closes palette + returns to grid,
|
|
||||||
* number keys 1-9 jump directly to that item.
|
|
||||||
* @param {KeyboardEvent} e
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
async function handlePaletteKeydown(e) {
|
|
||||||
const visibleCount = Math.min(_paletteFilteredSessions.length, PALETTE_MAX_ITEMS);
|
|
||||||
|
|
||||||
if (e.key === 'Escape') {
|
|
||||||
e.preventDefault();
|
|
||||||
closePalette();
|
|
||||||
} else if (e.key === 'g' || e.key === 'G') {
|
|
||||||
e.preventDefault();
|
|
||||||
closePalette();
|
|
||||||
await closeSession();
|
|
||||||
} else if (visibleCount > 0) {
|
|
||||||
if (e.key === 'ArrowDown') {
|
|
||||||
e.preventDefault();
|
|
||||||
_paletteSelectedIndex = (_paletteSelectedIndex + 1) % visibleCount;
|
|
||||||
highlightPaletteItem(_paletteSelectedIndex);
|
|
||||||
} else if (e.key === 'ArrowUp') {
|
|
||||||
e.preventDefault();
|
|
||||||
_paletteSelectedIndex = (_paletteSelectedIndex - 1 + visibleCount) % visibleCount;
|
|
||||||
highlightPaletteItem(_paletteSelectedIndex);
|
|
||||||
} else if (e.key === 'Enter') {
|
|
||||||
e.preventDefault();
|
|
||||||
const session = _paletteFilteredSessions[_paletteSelectedIndex];
|
|
||||||
if (session) {
|
|
||||||
closePalette();
|
|
||||||
await openSession(session.name);
|
|
||||||
}
|
|
||||||
} else if (e.key >= '1' && e.key <= '9') {
|
|
||||||
const idx = parseInt(e.key, 10) - 1;
|
|
||||||
if (idx < visibleCount) {
|
|
||||||
e.preventDefault();
|
|
||||||
const session = _paletteFilteredSessions[idx];
|
|
||||||
closePalette();
|
|
||||||
await openSession(session.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global keydown handler.
|
* Global keydown handler.
|
||||||
* When palette is open: delegates to handlePaletteKeydown.
|
* When in fullscreen: Escape returns to grid.
|
||||||
* When in fullscreen with palette closed: backtick or Ctrl+K opens palette,
|
|
||||||
* Escape returns to grid.
|
|
||||||
* @param {KeyboardEvent} e
|
* @param {KeyboardEvent} e
|
||||||
*/
|
*/
|
||||||
function handleGlobalKeydown(e) {
|
function handleGlobalKeydown(e) {
|
||||||
if (_paletteOpen) {
|
|
||||||
handlePaletteKeydown(e).catch((err) => console.error('[handleGlobalKeydown]', err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_viewMode === 'fullscreen') {
|
if (_viewMode === 'fullscreen') {
|
||||||
if (e.key === '`' || (e.ctrlKey && e.key === 'k')) {
|
if (e.key === 'Escape') {
|
||||||
e.preventDefault();
|
|
||||||
openPalette();
|
|
||||||
} else if (e.key === 'Escape') {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
closeSession();
|
closeSession();
|
||||||
}
|
}
|
||||||
@@ -1166,8 +993,6 @@ function bindStaticEventListeners() {
|
|||||||
on($('sidebar-toggle-btn'), 'click', toggleSidebar);
|
on($('sidebar-toggle-btn'), 'click', toggleSidebar);
|
||||||
on($('sidebar-collapse-btn'), 'click', toggleSidebar);
|
on($('sidebar-collapse-btn'), 'click', toggleSidebar);
|
||||||
bindSidebarClickAway();
|
bindSidebarClickAway();
|
||||||
on($('palette-trigger'), 'click', openPalette);
|
|
||||||
on($('palette-backdrop'), 'click', closePalette);
|
|
||||||
document.addEventListener('keydown', handleGlobalKeydown);
|
document.addEventListener('keydown', handleGlobalKeydown);
|
||||||
on($('session-pill'), 'click', openBottomSheet);
|
on($('session-pill'), 'click', openBottomSheet);
|
||||||
on($('sheet-backdrop'), 'click', closeBottomSheet);
|
on($('sheet-backdrop'), 'click', closeBottomSheet);
|
||||||
@@ -1216,36 +1041,6 @@ function _setCurrentSessions(sessions) {
|
|||||||
_currentSessions = sessions;
|
_currentSessions = sessions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Test-only: set _paletteFilteredSessions directly. */
|
|
||||||
function _setPaletteFilteredSessions(sessions) {
|
|
||||||
_paletteFilteredSessions = sessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Test-only: get _paletteFilteredSessions. */
|
|
||||||
function _getPaletteFilteredSessions() {
|
|
||||||
return _paletteFilteredSessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Test-only: set _paletteSelectedIndex directly. */
|
|
||||||
function _setPaletteSelectedIndex(index) {
|
|
||||||
_paletteSelectedIndex = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Test-only: get _paletteSelectedIndex. */
|
|
||||||
function _getPaletteSelectedIndex() {
|
|
||||||
return _paletteSelectedIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Test-only: set _paletteOpen directly. */
|
|
||||||
function _setPaletteOpen(val) {
|
|
||||||
_paletteOpen = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Test-only: get _paletteOpen. */
|
|
||||||
function _isPaletteOpen() {
|
|
||||||
return _paletteOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Test-only: set _viewMode directly. */
|
/** Test-only: set _viewMode directly. */
|
||||||
function _setViewMode(mode) {
|
function _setViewMode(mode) {
|
||||||
_viewMode = mode;
|
_viewMode = mode;
|
||||||
@@ -1301,13 +1096,6 @@ if (typeof module !== 'undefined' && module.exports) {
|
|||||||
openSession,
|
openSession,
|
||||||
closeSession,
|
closeSession,
|
||||||
_setViewingSession,
|
_setViewingSession,
|
||||||
// Command palette
|
|
||||||
renderPaletteList,
|
|
||||||
highlightPaletteItem,
|
|
||||||
openPalette,
|
|
||||||
closePalette,
|
|
||||||
onPaletteInput,
|
|
||||||
handlePaletteKeydown,
|
|
||||||
handleGlobalKeydown,
|
handleGlobalKeydown,
|
||||||
bindStaticEventListeners,
|
bindStaticEventListeners,
|
||||||
openBottomSheet,
|
openBottomSheet,
|
||||||
@@ -1323,12 +1111,6 @@ if (typeof module !== 'undefined' && module.exports) {
|
|||||||
hidePreview,
|
hidePreview,
|
||||||
// Test-only helpers
|
// Test-only helpers
|
||||||
_setCurrentSessions,
|
_setCurrentSessions,
|
||||||
_setPaletteFilteredSessions,
|
|
||||||
_getPaletteFilteredSessions,
|
|
||||||
_setPaletteSelectedIndex,
|
|
||||||
_getPaletteSelectedIndex,
|
|
||||||
_setPaletteOpen,
|
|
||||||
_isPaletteOpen,
|
|
||||||
_setViewMode,
|
_setViewMode,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,330 @@
|
|||||||
|
"""Tests for frontend/app.js — verifies palette code removal and handleGlobalKeydown simplification."""
|
||||||
|
|
||||||
|
import pathlib
|
||||||
|
import re
|
||||||
|
|
||||||
|
JS_PATH = pathlib.Path(__file__).parent.parent / "frontend" / "app.js"
|
||||||
|
|
||||||
|
# Read once per module — tests are read-only so sharing is safe.
|
||||||
|
_JS: str = JS_PATH.read_text()
|
||||||
|
|
||||||
|
|
||||||
|
# ── Palette state variables must be removed ──────────────────────────────────
|
||||||
|
|
||||||
|
def test_no_palette_max_items_constant() -> None:
|
||||||
|
"""PALETTE_MAX_ITEMS constant must be removed."""
|
||||||
|
assert "PALETTE_MAX_ITEMS" not in _JS, (
|
||||||
|
"PALETTE_MAX_ITEMS must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_palette_selected_index_variable() -> None:
|
||||||
|
"""_paletteSelectedIndex variable must be removed."""
|
||||||
|
assert "_paletteSelectedIndex" not in _JS, (
|
||||||
|
"_paletteSelectedIndex must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_palette_filtered_sessions_variable() -> None:
|
||||||
|
"""_paletteFilteredSessions variable must be removed."""
|
||||||
|
assert "_paletteFilteredSessions" not in _JS, (
|
||||||
|
"_paletteFilteredSessions must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_palette_open_variable() -> None:
|
||||||
|
"""_paletteOpen variable must be removed."""
|
||||||
|
assert "_paletteOpen" not in _JS, (
|
||||||
|
"_paletteOpen must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_palette_input_listener_variable() -> None:
|
||||||
|
"""_paletteInputListener variable must be removed."""
|
||||||
|
assert "_paletteInputListener" not in _JS, (
|
||||||
|
"_paletteInputListener must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ── Palette functions must be removed ────────────────────────────────────────
|
||||||
|
|
||||||
|
def test_no_render_palette_list_function() -> None:
|
||||||
|
"""renderPaletteList function must be removed."""
|
||||||
|
assert "renderPaletteList" not in _JS, (
|
||||||
|
"renderPaletteList must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_highlight_palette_item_function() -> None:
|
||||||
|
"""highlightPaletteItem function must be removed."""
|
||||||
|
assert "highlightPaletteItem" not in _JS, (
|
||||||
|
"highlightPaletteItem must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_open_palette_function() -> None:
|
||||||
|
"""openPalette function must be removed."""
|
||||||
|
assert "openPalette" not in _JS, (
|
||||||
|
"openPalette must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_close_palette_function() -> None:
|
||||||
|
"""closePalette function must be removed."""
|
||||||
|
assert "closePalette" not in _JS, (
|
||||||
|
"closePalette must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_on_palette_input_function() -> None:
|
||||||
|
"""onPaletteInput function must be removed."""
|
||||||
|
assert "onPaletteInput" not in _JS, (
|
||||||
|
"onPaletteInput must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_handle_palette_keydown_function() -> None:
|
||||||
|
"""handlePaletteKeydown function must be removed."""
|
||||||
|
assert "handlePaletteKeydown" not in _JS, (
|
||||||
|
"handlePaletteKeydown must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ── handleGlobalKeydown must be simplified ───────────────────────────────────
|
||||||
|
|
||||||
|
def test_handle_global_keydown_exists() -> None:
|
||||||
|
"""handleGlobalKeydown function must exist."""
|
||||||
|
assert "function handleGlobalKeydown" in _JS, (
|
||||||
|
"handleGlobalKeydown must still exist in app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_handle_global_keydown_no_palette_open_check() -> None:
|
||||||
|
"""handleGlobalKeydown must not check _paletteOpen."""
|
||||||
|
# Extract the function body
|
||||||
|
match = re.search(
|
||||||
|
r"function handleGlobalKeydown\s*\(e\)\s*\{(.*?)\n\}",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "handleGlobalKeydown function not found"
|
||||||
|
body = match.group(1)
|
||||||
|
assert "_paletteOpen" not in body, (
|
||||||
|
"handleGlobalKeydown must not reference _paletteOpen"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_handle_global_keydown_no_open_palette_call() -> None:
|
||||||
|
"""handleGlobalKeydown must not call openPalette."""
|
||||||
|
match = re.search(
|
||||||
|
r"function handleGlobalKeydown\s*\(e\)\s*\{(.*?)\n\}",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "handleGlobalKeydown function not found"
|
||||||
|
body = match.group(1)
|
||||||
|
assert "openPalette" not in body, (
|
||||||
|
"handleGlobalKeydown must not call openPalette"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_handle_global_keydown_handles_escape_in_fullscreen() -> None:
|
||||||
|
"""handleGlobalKeydown must call closeSession() on Escape in fullscreen mode."""
|
||||||
|
match = re.search(
|
||||||
|
r"function handleGlobalKeydown\s*\(e\)\s*\{(.*?)\n\}",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "handleGlobalKeydown function not found"
|
||||||
|
body = match.group(1)
|
||||||
|
assert "fullscreen" in body, "handleGlobalKeydown must check for fullscreen mode"
|
||||||
|
assert "Escape" in body, "handleGlobalKeydown must handle Escape key"
|
||||||
|
assert "closeSession" in body, "handleGlobalKeydown must call closeSession"
|
||||||
|
|
||||||
|
|
||||||
|
# ── bindStaticEventListeners must have no palette references ─────────────────
|
||||||
|
|
||||||
|
def test_bind_static_event_listeners_no_palette_trigger() -> None:
|
||||||
|
"""bindStaticEventListeners must not bind palette-trigger click."""
|
||||||
|
match = re.search(
|
||||||
|
r"function bindStaticEventListeners\s*\(\s*\)\s*\{(.*?)\n\}",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "bindStaticEventListeners function not found"
|
||||||
|
body = match.group(1)
|
||||||
|
assert "palette-trigger" not in body, (
|
||||||
|
"bindStaticEventListeners must not bind palette-trigger click"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_bind_static_event_listeners_no_palette_backdrop() -> None:
|
||||||
|
"""bindStaticEventListeners must not bind palette-backdrop click."""
|
||||||
|
match = re.search(
|
||||||
|
r"function bindStaticEventListeners\s*\(\s*\)\s*\{(.*?)\n\}",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "bindStaticEventListeners function not found"
|
||||||
|
body = match.group(1)
|
||||||
|
assert "palette-backdrop" not in body, (
|
||||||
|
"bindStaticEventListeners must not bind palette-backdrop click"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ── Palette test-only helpers must be removed ─────────────────────────────────
|
||||||
|
|
||||||
|
def test_no_set_palette_filtered_sessions_helper() -> None:
|
||||||
|
"""_setPaletteFilteredSessions test helper must be removed."""
|
||||||
|
assert "_setPaletteFilteredSessions" not in _JS, (
|
||||||
|
"_setPaletteFilteredSessions must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_get_palette_filtered_sessions_helper() -> None:
|
||||||
|
"""_getPaletteFilteredSessions test helper must be removed."""
|
||||||
|
assert "_getPaletteFilteredSessions" not in _JS, (
|
||||||
|
"_getPaletteFilteredSessions must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_set_palette_selected_index_helper() -> None:
|
||||||
|
"""_setPaletteSelectedIndex test helper must be removed."""
|
||||||
|
assert "_setPaletteSelectedIndex" not in _JS, (
|
||||||
|
"_setPaletteSelectedIndex must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_get_palette_selected_index_helper() -> None:
|
||||||
|
"""_getPaletteSelectedIndex test helper must be removed."""
|
||||||
|
assert "_getPaletteSelectedIndex" not in _JS, (
|
||||||
|
"_getPaletteSelectedIndex must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_set_palette_open_helper() -> None:
|
||||||
|
"""_setPaletteOpen test helper must be removed."""
|
||||||
|
assert "_setPaletteOpen" not in _JS, (
|
||||||
|
"_setPaletteOpen must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_is_palette_open_helper() -> None:
|
||||||
|
"""_isPaletteOpen test helper must be removed."""
|
||||||
|
assert "_isPaletteOpen" not in _JS, (
|
||||||
|
"_isPaletteOpen must be removed from app.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ── module.exports must not include palette exports ───────────────────────────
|
||||||
|
|
||||||
|
def test_exports_no_render_palette_list() -> None:
|
||||||
|
"""module.exports must not export renderPaletteList."""
|
||||||
|
match = re.search(
|
||||||
|
r"module\.exports\s*=\s*\{(.*?)\};",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "module.exports block not found"
|
||||||
|
exports = match.group(1)
|
||||||
|
assert "renderPaletteList" not in exports, (
|
||||||
|
"module.exports must not export renderPaletteList"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_exports_no_highlight_palette_item() -> None:
|
||||||
|
"""module.exports must not export highlightPaletteItem."""
|
||||||
|
match = re.search(
|
||||||
|
r"module\.exports\s*=\s*\{(.*?)\};",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "module.exports block not found"
|
||||||
|
exports = match.group(1)
|
||||||
|
assert "highlightPaletteItem" not in exports, (
|
||||||
|
"module.exports must not export highlightPaletteItem"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_exports_no_open_palette() -> None:
|
||||||
|
"""module.exports must not export openPalette."""
|
||||||
|
match = re.search(
|
||||||
|
r"module\.exports\s*=\s*\{(.*?)\};",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "module.exports block not found"
|
||||||
|
exports = match.group(1)
|
||||||
|
assert "openPalette" not in exports, (
|
||||||
|
"module.exports must not export openPalette"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_exports_no_close_palette() -> None:
|
||||||
|
"""module.exports must not export closePalette."""
|
||||||
|
match = re.search(
|
||||||
|
r"module\.exports\s*=\s*\{(.*?)\};",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "module.exports block not found"
|
||||||
|
exports = match.group(1)
|
||||||
|
assert "closePalette" not in exports, (
|
||||||
|
"module.exports must not export closePalette"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_exports_no_on_palette_input() -> None:
|
||||||
|
"""module.exports must not export onPaletteInput."""
|
||||||
|
match = re.search(
|
||||||
|
r"module\.exports\s*=\s*\{(.*?)\};",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "module.exports block not found"
|
||||||
|
exports = match.group(1)
|
||||||
|
assert "onPaletteInput" not in exports, (
|
||||||
|
"module.exports must not export onPaletteInput"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_exports_no_handle_palette_keydown() -> None:
|
||||||
|
"""module.exports must not export handlePaletteKeydown."""
|
||||||
|
match = re.search(
|
||||||
|
r"module\.exports\s*=\s*\{(.*?)\};",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "module.exports block not found"
|
||||||
|
exports = match.group(1)
|
||||||
|
assert "handlePaletteKeydown" not in exports, (
|
||||||
|
"module.exports must not export handlePaletteKeydown"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_exports_still_has_handle_global_keydown() -> None:
|
||||||
|
"""module.exports must still export handleGlobalKeydown."""
|
||||||
|
match = re.search(
|
||||||
|
r"module\.exports\s*=\s*\{(.*?)\};",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "module.exports block not found"
|
||||||
|
exports = match.group(1)
|
||||||
|
assert "handleGlobalKeydown" in exports, (
|
||||||
|
"module.exports must still export handleGlobalKeydown"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_exports_still_has_bind_static_event_listeners() -> None:
|
||||||
|
"""module.exports must still export bindStaticEventListeners."""
|
||||||
|
match = re.search(
|
||||||
|
r"module\.exports\s*=\s*\{(.*?)\};",
|
||||||
|
_JS,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
assert match, "module.exports block not found"
|
||||||
|
exports = match.group(1)
|
||||||
|
assert "bindStaticEventListeners" in exports, (
|
||||||
|
"module.exports must still export bindStaticEventListeners"
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user