diff --git a/src/AnnotationControl/annotationPanel.js b/src/AnnotationControl/annotationPanel.js index 86706dc..2bb5595 100644 --- a/src/AnnotationControl/annotationPanel.js +++ b/src/AnnotationControl/annotationPanel.js @@ -138,16 +138,17 @@ export function initAnnotationsPanel(viewer) { } } + + /** + * Find the live annotation object in the viewer.scene by UUID. + * + * Returns the live annotation or null. + * + * @param {string} uuid - annotation UUID + * @returns {Object|null} live annotation object or null if not found + */ function _getAnnotationsRoot() { const t = _getJSTree() - /** - * Find the live annotation object in the viewer.scene by UUID. - * - * Returns the live annotation or null. - * - * @param {string} uuid - annotation UUID - * @returns {Object|null} live annotation object or null if not found - */ try { return t ? t.get_json('annotations') : null } catch (e) { @@ -229,24 +230,25 @@ export function initAnnotationsPanel(viewer) { } return null } + + /** + * Rebuild the annotation list UI from the project's jsTree data. + * + * This function: + * - Clears and re-populates the `targetContainer` with a row per annotation. + * - Ensures default labels for unnamed annotations (using monotonic numbering). + * - Renders header, toggle triangle, edit label, jump/delete controls, description, + * and read-only camera/point info. + * - Wires events for inline editing, jump, delete, and header click-to-toggle. + * + * Side effects: + * - Mutates DOM inside `targetContainer`. + * - May call `_renameJSTreeNode` to rename nodes when needed. + * - Uses `_findLiveAnnotationByUUID` to prefer live object positions over serialized values. + * - Event listeners stop propagation where necessary so double-click and button + * behaviour are preserved. + */ function updateAnnotationsList() { - /** - * Rebuild the annotation list UI from the project's jsTree data. - * - * This function: - * - Clears and re-populates the `targetContainer` with a row per annotation. - * - Ensures default labels for unnamed annotations (using monotonic numbering). - * - Renders header, toggle triangle, edit label, jump/delete controls, description, - * and read-only camera/point info. - * - Wires events for inline editing, jump, delete, and header click-to-toggle. - * - * Side effects: - * - Mutates DOM inside `targetContainer`. - * - May call `_renameJSTreeNode` to rename nodes when needed. - * - Uses `_findLiveAnnotationByUUID` to prefer live object positions over serialized values. - * - Event listeners stop propagation where necessary so double-click and button - * behaviour are preserved. - */ // Implementation for listing annotations targetContainer.innerHTML = '' const annotationsTree = _getJSTree() @@ -603,21 +605,21 @@ export function initAnnotationsPanel(viewer) { }) } + /** + * Start inline editing of an annotation title (opens an input in the sidebar). + * + * Replaces the `.annotation-label` with a text input and handles commit/abort: + * - On commit, updates the label in the sidebar, updates the jsTree node text, + * and updates the live annotation object's title (via `_commitEditedName`). + * - On abort, restores the original label without committing. + * + * Special handling: + * - If the label contains a decorative edit-hint span, the hint text is not + * included in the input value and is re-attached to the restored label. + * + * @param {string} uuid - annotation UUID to edit + */ function startInlineEditForUUID(uuid) { - /** - * Start inline editing of an annotation title (opens an input in the sidebar). - * - * Replaces the `.annotation-label` with a text input and handles commit/abort: - * - On commit, updates the label in the sidebar, updates the jsTree node text, - * and updates the live annotation object's title (via `_commitEditedName`). - * - On abort, restores the original label without committing. - * - * Special handling: - * - If the label contains a decorative edit-hint span, the hint text is not - * included in the input value and is re-attached to the restored label. - * - * @param {string} uuid - annotation UUID to edit - */ if (!uuid) return const labelEl = targetContainer.querySelector( `.annotation-label[data-uuid="${uuid}"]` @@ -703,16 +705,16 @@ export function initAnnotationsPanel(viewer) { }) } + /** + * Start inline editing of an annotation description (multiline). + * + * Replaces the `.annotation-desc` container with a textarea. Behavior mirrors + * `startInlineEditForUUID` but handles multiline input. Commit updates both + * the jsTree node data and the live annotation object's description. + * + * @param {string} uuid - annotation UUID to edit + */ function startInlineDescriptionEditForUUID(uuid) { - /** - * Start inline editing of an annotation description (multiline). - * - * Replaces the `.annotation-desc` container with a textarea. Behavior mirrors - * `startInlineEditForUUID` but handles multiline input. Commit updates both - * the jsTree node data and the live annotation object's description. - * - * @param {string} uuid - annotation UUID to edit - */ if (!uuid) return const descEl = targetContainer.querySelector( `.annotation-desc[data-uuid="${uuid}"]` @@ -741,6 +743,15 @@ export function initAnnotationsPanel(viewer) { ta.select() } catch (e) {} + + /** + * Finish editing the description textarea. + * + * Replaces the textarea with a `.annotation-desc`, re-attaches handlers, + * and persists (or discards) the change via _commitEditedDescription. + * + * @param {boolean} commit - true to save, false to cancel + */ function finish(commit) { const newText = commit ? ta.value.trim() || '' : oldText const displayText = newText ? newText : 'Annotation Description' @@ -802,15 +813,15 @@ export function initAnnotationsPanel(viewer) { }) } + /** + * Commit a changed annotation description to jsTree and to the live annotation. + * + * Also updates any cached node data used by the sidebar. + * + * @param {string} uuid - annotation UUID + * @param {string} description - new description text + */ function _commitEditedDescription(uuid, description) { - /** - * Commit a changed annotation description to jsTree and to the live annotation. - * - * Also updates any cached node data used by the sidebar. - * - * @param {string} uuid - annotation UUID - * @param {string} description - new description text - */ if (!uuid) return try { const tree = _getJSTree() @@ -852,16 +863,16 @@ export function initAnnotationsPanel(viewer) { setTimeout(updateAnnotationsList, 0) } + /** + * Commit a changed annotation name to jsTree and to the live annotation object. + * + * This updates the jsTree node text (if accessible) and mutates the live + * annotation instance's title/name/data so the viewer label matches. + * + * @param {string} uuid - annotation UUID + * @param {string} name - new name to commit + */ function _commitEditedName(uuid, name) { - /** - * Commit a changed annotation name to jsTree and to the live annotation object. - * - * This updates the jsTree node text (if accessible) and mutates the live - * annotation instance's title/name/data so the viewer label matches. - * - * @param {string} uuid - annotation UUID - * @param {string} name - new name to commit - */ if (!uuid) return // update jsTree node text try { @@ -894,18 +905,18 @@ export function initAnnotationsPanel(viewer) { setTimeout(updateAnnotationsList, 0) } + /** + * Create and insert the "Add a location" button for annotations. + * + * The button: + * - Captures the current camera view when clicked. + * - Starts Potree's annotation insertion mode. + * - Waits for placement completion and triggers `updateAnnotationsList`. + * + * Side effects: + * - Inserts a button into the DOM near the annotations list. + */ function createAddButton() { - /** - * Create and insert the "Add a location" button for annotations. - * - * The button: - * - Captures the current camera view when clicked. - * - Starts Potree's annotation insertion mode. - * - Waits for placement completion and triggers `updateAnnotationsList`. - * - * Side effects: - * - Inserts a button into the DOM near the annotations list. - */ const btn = document.createElement('button') btn.className = 'annotation-add-button' btn.setAttribute('aria-label', 'Add a new saved location')