Skip to content

fix(map): expose L_.Map_ before makeLayers to prevent race condition#986

Merged
tariqksoliman merged 573 commits into
NASA-AMMOS:developmentfrom
JPL-Devin:development
May 26, 2026
Merged

fix(map): expose L_.Map_ before makeLayers to prevent race condition#986
tariqksoliman merged 573 commits into
NASA-AMMOS:developmentfrom
JPL-Devin:development

Conversation

@tariqksoliman

Copy link
Copy Markdown
Member

With Devin: JPL-Devin#85

Purpose

  • Fix a race condition where AJAX callbacks from makeLayers try to access L_.Map_.map.getZoom() while L_.Map_ is still null because L_.fina() hasn't been called yet.

Proposed Changes

  • [FIX] Add L_.Map_ = this immediately before the makeLayers(L_.layers.dataFlat) call in src/essence/Basics/Map_/Map_.js (line ~290). This ensures L_.Map_.map is the fully initialized Leaflet map instance by the time any AJAX callback resolves.

Issues

  • Race condition: makeLayerscaptureVector$.getJSON callbacks resolve and call L_.Map_.map.getZoom() before L_.fina() assigns L_.Map_.

devin-ai-integration Bot and others added 30 commits April 30, 2026 23:59
…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>
devin-ai-integration Bot and others added 25 commits May 21, 2026 21:57
- 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
@tariqksoliman tariqksoliman self-assigned this May 26, 2026
@tariqksoliman tariqksoliman added the bug Something isn't working label May 26, 2026
@tariqksoliman tariqksoliman merged commit 4cb7693 into NASA-AMMOS:development May 26, 2026
4 of 7 checks passed
@github-project-automation github-project-automation Bot moved this to Done in MMGIS May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant