fix(map): expose L_.Map_ before makeLayers to prevent race condition#986
Merged
Conversation
…d rows - MobileTimeUIToggle now opens/closes the tool panel via ToolController_ - Closes any active tool before showing TimeUI - Forces expanded state when opening - CSS hides start time inputs, positions expanded content properly - Overrides absolute positioning of expanded content for tool panel flow Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
- Add separatedToolsList/activeSeparatedTools state to Zustand uiStore - Rewrite SeparatedTools.jsx with glassmorphism panels, CSS Module styling - Replace SepToolsContainer (setInterval hack) with SepToolButton/SepToolsSection - Remove ~170 lines of jQuery DOM construction from ToolController_.js - Fix hardcoded rgba(26,26,27,0.88) to theme-aware var(--color-a-rgb) - Remove separated tool entries from themeApplier.js - Remove separated tool overrides from FloatingElements.css - Move Legend CSS overrides from Toolbar.module.css to SeparatedTools.module.css - Remove jQuery active-state manipulation from IdentifierTool.js - Add store sync in Map_.js displayOnStart logic - Preserve all DOM IDs for backward compatibility (mmgisAPI, tool make()) Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…face_ L_.UserInterface_ is null when TimeUI.init() runs (TimeControl.init is called before L_.link sets UserInterface_). All 16 isMobile checks now read from useUIStore.getState().isMobile which is set at startup. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…zeTools() - Map_ no longer references specific tools (LegendTool) - displayOnStart is now handled generically for all separated tools - Added DOM element polling (tryMake) to handle React render timing Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Reverts TimeUI.js and BottomBar.js to development base. Restores #timeUI DOM removal in UserInterfaceBridge.fina(). Removes MobileTimeUIToggle component from Toolbar.jsx. Removes TimeUI mobile CSS overrides from UserInterfaceMobile_.css. Non-TimeUI refinements (toolbar height, scalebar positioning, etc.) preserved. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
LegendTool handles its own content lifecycle via subscribeOnLayerToggle. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…bar toggle - TimeUI.js: import useUIStore and replace all 16 L_.UserInterface_?.isMobile checks with useUIStore.getState().isMobile (L_.UserInterface_ is null when TimeUI.init() runs, so mobile conditionals were dead code) - TimeUI.js: stage mobile #timeUI in hidden #timeUIMobileStaging instead of placing directly in #tools (which gets cleared by other tools) - UserInterfaceBridge.js: stop removing #timeUI from DOM on mobile - Toolbar.jsx: add MobileTimeUIToggle that moves #timeUI between staging and #tools, opens/closes tool panel via ToolController_ - BottomBar.js: hide TimeUI toggle from settings modal on mobile Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Subscribe to activeToolName changes — when a tool becomes active while TimeUI is showing, move #timeUI back to #timeUIMobileStaging before the new tool's make() clears #tools. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…issues - Remove separatedTool checkbox and justification dropdown from Legend and Identifier config.json (these are always separated, not configurable) - Remove justification property/code from LegendTool.js, IdentifierTool.js - Simplify Globe_.js separated tool count (no justification filter) - Remove justification from Reference-Mission config blueprint - Update LegendTool help docs and Legend.md documentation - Add --color-a-rgb fallback (29,31,32) in SeparatedTools.module.css - Add display:none !important to .panelIdentifier to prevent 12px gap - Update e2e test comment Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
… sync - TimeUI.js: replace top-level useUIStore import with lazy _getUIStore() accessor to avoid 'Cannot access useUIStore before initialization' circular import error at _remakeTimeSlider - SplitScreens.jsx: skip #timeUI reparenting observer on mobile (mobile uses MobileTimeUIToggle to manage #timeUI placement in #tools) - BottomElementPositioner.jsx: unify mobile transition to 0.3s (matches toolsWrapper and toolbar), guard pxIsTools against undefined - Toolbar.jsx: align toolbar transition to 0.3s ease-out Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…d-tools feat: rewrite separated tools system from jQuery to React components
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…set) _makeHistogram renders inside the timeline slider which doesn't exist on mobile. Without it, _timelineStartTimestamp is NaN, causing 'Invalid time value' RangeError at toISOString(). Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…nel height - TimeUI.js attachEvents: use _initialStart/_initialEnd on mobile (same as desktop) instead of L_.TimeControl_ which isn't set yet at init time. Fixes 'Invalid date' in start/end time inputs. - TimeUI.js fina: set expanded=true on mobile and call _populateExpandedRows() so year/month/day/hour rows actually render. Removed position:absolute and pointer-events:none overrides. - Toolbar.jsx: set tool panel height to 217px (TimeUI.height) instead of 45% viewport — matches actual TimeUI content height. - UserInterfaceMobile_.css: expanded content flows naturally (position:relative), hide start time inputs, allow overflow scroll, flex-wrap topbar. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
- Add justify-content: center to #mmgisTimeUIMain on mobile - Remove border-bottom: none override so toolbar keeps its default border Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…fset - #timeUI overflow-y: hidden (was auto, causing 2px scroll) - Scalebar/compass/map controls stay at fixed 40px offset (above toolbar) regardless of tool panel state — no longer shift up by pxIsTools Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
- Restructure AGENTS.md from 745 lines to 106 lines (Tier 1: essential context) - Create knowledge/ directory with 30+ wiki-style documentation files (Tier 2: deep knowledge) - Create knowledge/reference/ with 8 detailed reference files (Tier 3: lookup material) - Move AI-GETTING-STARTED.md and AI-DEVELOPMENT.md to knowledge/ - Update all file references in .specify/templates and blueprints - Create knowledge/README.md as the full knowledge base index - Create knowledge/reference/README.md as reference material index Three-tier knowledge discovery system: Tier 1: AGENTS.md (~106 lines) - scannable in <2 minutes Tier 2: knowledge/*.md - deep knowledge on architecture, tools, APIs, DB, infra Tier 3: knowledge/reference/*.md - coding conventions, API reference, troubleshooting Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…gnment - All mobile toolbar buttons (ToolButton, MobileCoordButton, MobileTimeUIToggle) now use display:flex with align-items/justify-content center for proper vertical icon centering - MobileCoordButton: changed 'active' class to 'toolButtonActive' to match the global CSS active style (color-mmgis + color-i background) - Removed inline color overrides so CSS .toolButtonActive takes effect Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Include curated lessons learned from past Devin sessions: - CI/CD: ignore build-arm64/amd64 failures, focus on required checks - Child sessions: no separate PRs when consolidating - ENV triple-update rule (.env, sample.env, ENVs.md) - Error handling: use logger with infrastructure_error for fatal startup errors - Path traversal security: stay within /Missions, handle subpath serving - Database initialization architecture and migration patterns - API authentication behavior across AUTH modes - Auto-generated MMGIS concept index Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…ation - Active toolbar buttons get desktop-matching margin (1px 0) and border-radius (8px) via .toolButton.toolButtonActive CSS rule - Removed line-height: 40px from .toolButton (flex centering handles vertical alignment, line-height was pushing icons up) - MobileCoordButton now watches activeToolName store and deactivates when another tool opens (fixes coords staying active) - MobileTimeUIToggle sets activeToolName='MobileTimeUI' when opening so coords/other buttons can detect it and deactivate - MobileTimeUIToggle clears activeToolName when closing - Both custom buttons skip self-deactivation via name check Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…vin knowledge notes Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
- #toolbar .toolButton i: height 40px fixes icon vertical alignment - #toolbar .toolButton: margin 0 2px gives spacing between buttons - #toolbar .toolButton.toolButtonActive: margin 1px 2px so active background has visual padding around the icon Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…ntion Dot-prefix signals agent infrastructure (not source code), consistent with .specify/, .github/, .vscode/ conventions. All cross-references updated. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…height - Coord and TimeUI button <i> icons get line-height: 40px - Active buttons: height 34px (vs 40px toolbar) creates visual padding around the active background, centered by flex align-items - Buttons get margin: 0 1px for horizontal spacing Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
- Add permissions blocks to all workflow files - Pin all third-party actions to commit SHAs - Replace node -e require(package.json) with jq in bump-version.yml Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Add sanitizeForLog() to strip ANSI escape sequences and control characters from log messages, callers, and errors in both dev and production modes. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…t guide - Move Reference-Mission/README.md to blueprints/README.md - Add 'Adding a New Reference Mission Variant' step-by-step guide - Document all existing variants (Earth default, Lunar South Pole) - Update cross-references in AGENTS.md and .knowledge/code-patterns.md Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
- Add DOMPurify dependency and Sanitize.js service module - Apply safeHTML() to CursorInfo, Modal, DrawTool_Files, DrawTool_Templater - Replace .html() with .text() for numeric labels in LayersTool - Escape single quotes in Filtering attribute values Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Move /public, /README.md, and /examples static routes before session middleware to avoid setting unnecessary cookies on public assets. Authenticated routes (/build, /configure/*) remain after session. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
- DOM XSS tests: remove document API usage (not available in Node context) - Geodatasets: array format correctly defaults to safe string, not rejected - Prototype pollution: use hasOwnProperty.call instead of direct property access Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
- Rate limiters: wrap in deferred closure so lookup happens at request time, not module load time (users.js login + 6 utils.js compute routes) - docker-build.yml: restore step-level env: blocks that were incorrectly replaced with permissions: at wrong indentation level Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…le blueprint Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…sect - authLimiter: skip for token-based re-auth (req.body.useToken) to avoid locking out legitimate users on page refresh - geodatasets.js: apply same typeof string coercion to POST /intersect endpoint that was applied to GET endpoints Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Prevents bypass where attacker sets useToken:true without a valid cookie to skip the rate limiter and brute-force credentials. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
- Auth rate limiter: parse cookie and require valid token before skipping rate limit (prevents bypass via crafted falsy cookie) - Modal.jsx: remove safeHTML (too restrictive for developer-authored modal content with forms, ids, inputs) - DrawTool_Files.js: escape file_name/intent/file_owner in title attribute to prevent attribute injection via single quotes Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…e-reference-mission feat: add Lunar South Pole reference mission variant (IAU2000:30120)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
- Sanitize.js: add ul, li tags and id attribute to allowlist for IdentifierTool cursor info compatibility - users.js: remove token-reauth bypass from authLimiter to prevent crafted-cookie abuse; rate limit applies to all /login requests Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Renamed .test.js to .spec.js (matches testMatch pattern) and converted from plain Node script to Playwright test.describe/test structure so it runs via npm test like all other tests. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
loginIfRequired now skips login for both AUTH=off and AUTH=none, preventing timeout when no login form is rendered. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
The control character regex now excludes \n (0x0A), \r (0x0D), and \t (0x09) so stack traces and multi-line messages remain readable in development mode. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
fix(security): apply 7 Sonar security recommendations with TDD
AJAX callbacks fired by makeLayers → captureVector → $.getJSON can resolve and access L_.Map_.map.getZoom() while L_.Map_ is still null because L_.fina() hasn't run yet. Setting L_.Map_ = this immediately before the makeLayers call ensures the Leaflet map instance is available to any callback. L_.fina() will still reassign to the same value later, so there is no conflict. Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
fix(map): expose L_.Map_ before makeLayers to prevent race condition
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With Devin: JPL-Devin#85
Purpose
makeLayerstry to accessL_.Map_.map.getZoom()whileL_.Map_is stillnullbecauseL_.fina()hasn't been called yet.Proposed Changes
L_.Map_ = thisimmediately before themakeLayers(L_.layers.dataFlat)call insrc/essence/Basics/Map_/Map_.js(line ~290). This ensuresL_.Map_.mapis the fully initialized Leaflet map instance by the time any AJAX callback resolves.Issues
makeLayers→captureVector→$.getJSONcallbacks resolve and callL_.Map_.map.getZoom()beforeL_.fina()assignsL_.Map_.