Skip to main content

JavaScript Modules Documentation

Last Updated: October 8, 2025 Purpose: External JavaScript modules for brandonjplambert portfolio site Architecture: Modular, single-responsibility, zero dependencies


Overview

This directory contains JavaScript modules extracted from inline code as part of the October 8, 2025 technical debt reduction (Plan B). All modules follow clean code principles: separation of concerns, single responsibility, and DRY (Don’t Repeat Yourself).

Migration History:

  • Before: 516 lines of inline JavaScript scattered across HTML files
  • After: 4 focused modules totaling 516 lines (organized, testable, reusable)
  • Reduction in HTML: ai-projects.html 994 → 167 lines (-83%)

Module Index

1. projects-filter.js (117 lines)

Purpose: Category filtering and navigation for AI projects page

Responsibilities:

  • Filter projects by category (All, Educational, Creative, Infrastructure)
  • Generate dynamic project list menu from visible projects
  • Handle smooth scroll navigation to specific projects
  • Apply highlight animation on project click

Key Functions:

  • filterProjects(category) - Filter and show/hide project cards
  • updateProjectList() - Regenerate sidebar navigation menu
  • scrollToProject(slug) - Smooth scroll to project with highlight

Usage:

<script src="/assets/js/projects-filter.js"></script>

Dependencies: None (vanilla JavaScript)


2. project-modal.js (113 lines)

Purpose: Development history modal rendering and interactions

Responsibilities:

  • Render full-screen modal with project development timeline
  • Display timeline phases (specification, pseudocode, architecture, etc.)
  • Generate stats grid (lines of code, commits, technologies)
  • Handle modal open/close interactions

Key Functions:

  • openModal(projectSlug) - Open modal for specific project
  • closeModal() - Close modal and cleanup
  • renderTimeline(phases) - Generate timeline HTML
  • renderStats(stats) - Generate stats grid HTML

Data Structure:

projectHistories = {
  'project-slug': {
    phases: [ /* timeline data */ ],
    stats: { /* metrics */ },
    transformations: [ /* before/after */ ]
  }
}

Usage:

<button onclick="openModal('describe_it')">View History</button>
<script src="/assets/js/project-modal.js"></script>

Dependencies:

  • Requires projectHistories object (generated inline via Liquid templates)

3. tech-tooltips.js (115 lines)

Purpose: Technology badge tooltip creation and positioning

Responsibilities:

  • Create tooltips with full technology names and descriptions
  • Position tooltips intelligently (avoid screen edges)
  • Handle both mouse hover and touch interactions
  • Auto-hide on scroll or click outside

Key Functions:

  • initTooltips() - Initialize all tech badges with tooltips
  • showTooltip(badge, content) - Display tooltip with positioning
  • hideTooltip(tooltip) - Hide and cleanup tooltip
  • positionTooltip(badge, tooltip) - Smart positioning logic

Technology Data:

<span class="tech-badge" data-tech="nextjs">
  Next.js|React framework for production
</span>

Usage:

<script src="/assets/js/tech-tooltips.js"></script>

Dependencies: None (vanilla JavaScript)


4. site-navigation.js (171 lines)

Purpose: Global navigation, mobile menu, and language switching

Responsibilities:

  • Header scroll effects (show/hide on scroll)
  • Mobile menu toggle/close functionality
  • Language switcher (EN ↔ ES) with data-driven path mapping
  • Language button active state management
  • Responsive navigation display updates

Key Functions:

  • initNavigation(config) - Main initialization with configuration
  • toggleMobileMenu() - Open/close mobile overlay
  • switchLanguage(lang) - Change language with path mapping
  • handleScroll() - Header visibility on scroll

Configuration Structure:

const navConfig = {
  currentLang: 'en',        // From Liquid: page.lang
  baseUrl: '',              // From Liquid: site.baseurl
  pathMap: {
    toSpanish: { '/work/': '/es/trabajo/', ... },
    toEnglish: { '/es/trabajo/': '/work/', ... }
  }
};

Usage:

<script src="/assets/js/site-navigation.js"></script>
<script>
  initNavigation({
    currentLang: 'en',
    baseUrl: '',
    pathMap: { /* ... */ }
  });
</script>

Dependencies:

  • Requires configuration object (generated inline via Liquid templates)
  • Uses ARIA attributes for accessibility

Architecture Principles

1. Single Responsibility Principle

Each module has ONE clear purpose:

  • projects-filter.js → Filtering only
  • project-modal.js → Modal rendering only
  • tech-tooltips.js → Tooltip behavior only
  • site-navigation.js → Navigation & language switching only

2. Separation of Concerns

  • HTML: Content and structure
  • CSS: Presentation (in _sass/ files)
  • JavaScript: Behavior (these modules)
  • Liquid: Server-side data generation

3. Zero Dependencies

All modules use vanilla JavaScript:

  • No jQuery
  • No external libraries
  • No npm packages required
  • Pure DOM manipulation

4. Progressive Enhancement

Modules check for required elements before initialization:

if (document.querySelector('.project-card')) {
  // Initialize only if elements exist
}

5. IIFE Pattern for Encapsulation

Modules use Immediately Invoked Function Expressions to avoid global scope pollution:

(function() {
  'use strict';
  // Module code here
})();

Integration with Jekyll/Liquid

Server-Side Data Injection

Some modules require data generated by Jekyll:

projects-filter.js & tech-tooltips.js:

  • No server-side data needed
  • Pure client-side functionality

project-modal.js:

  • Requires projectHistories object
  • Generated inline in HTML via Liquid loops
  • Contains development history for all projects

site-navigation.js:

  • Requires configuration object with pathMap
  • currentLang from page.lang
  • baseUrl from site.baseurl

Loading Order

  1. Modules loaded at end of <body> (non-blocking)
  2. Inline initialization scripts run after modules load
  3. DOM-ready checks prevent race conditions

Browser Compatibility

Tested Browsers:

  • ✅ Chrome 90+
  • ✅ Firefox 88+
  • ✅ Safari 14+
  • ✅ Edge 90+

JavaScript Features Used:

  • ES6 arrow functions
  • const/let declarations
  • Template literals
  • Array methods (forEach, filter, map)
  • querySelector/querySelectorAll
  • addEventListener
  • classList API
  • ARIA attributes

Fallbacks: None required (modern browsers only)


Performance Considerations

Module Size

projects-filter.js:  117 lines (~4.2 KB)
project-modal.js:    113 lines (~4.5 KB)
tech-tooltips.js:    115 lines (~4.1 KB)
site-navigation.js:  171 lines (~6.8 KB)
Total:              516 lines (~19.6 KB unminified)

Caching Strategy

  • Modules cached by browser (static assets)
  • HTML changes don’t require re-downloading JS
  • Faster subsequent page loads

Loading Performance

  • Before: 60KB inline (blocking render)
  • After: 12KB HTML + 20KB JS modules (async, cacheable)
  • Improvement: Better Core Web Vitals (LCP, FID)

Code Quality

  • Zero console.logs in production modules
  • All syntax validated before deployment
  • Clean, readable code for maintainability

Testing

Manual Testing Checklist

  • Project filtering works (all categories)
  • History modals open/close correctly
  • Technology tooltips appear on hover/touch
  • Mobile menu opens/closes smoothly
  • Language switching EN ↔ ES functional
  • Navigation responsive on mobile
  • Zero console errors in browser
  • Works on iOS Safari
  • Works on Android Chrome

Future: Automated Testing

Recommended: Add Jest for unit testing

// Example test
describe('projects-filter', () => {
  test('filters projects by category', () => {
    filterProjects('Educational');
    // Assert only educational projects visible
  });
});

Maintenance

Adding New Modules

  1. Create new .js file in this directory
  2. Follow IIFE pattern for encapsulation
  3. Use strict mode: 'use strict';
  4. Add DOM-ready checks
  5. Document in this README
  6. Test in multiple browsers
  7. Commit with clear message

Modifying Existing Modules

  1. Read module code and comments
  2. Make focused changes (single responsibility)
  3. Test functionality after changes
  4. Remove any console.logs before commit
  5. Update this README if API changes
  6. Commit with explanation of change

Debugging

  1. Open browser DevTools Console
  2. Check for JavaScript errors
  3. Use debugger statements or breakpoints
  4. Verify DOM elements exist
  5. Check ARIA attributes in inspector

Known Limitations

Inline Initialization Required

Some modules need server-side data from Liquid templates, requiring ~20 lines of inline initialization in HTML. This is an acceptable trade-off for Jekyll’s constraints.

No Build Pipeline

Currently no minification or bundling:

  • Modules served unminified
  • No source maps generated
  • No code splitting

Future Improvement: Add esbuild or Webpack for production optimization

No Automated Tests

Manual testing required after changes. High priority for future: add Jest test framework.


Future Enhancements

Short-term (Next Month)

  1. Add JSDoc comments to all functions
  2. Create test suite with Jest
  3. Minify modules for production
  4. Add source maps for debugging

Medium-term (Next Quarter)

  1. Migrate to ES6 modules (import/export)
  2. Add build pipeline (esbuild)
  3. Implement code splitting
  4. Add error tracking (Sentry)

Long-term (Next Year)

  1. Consider framework (React/Vue/Svelte)
  2. TypeScript migration for type safety
  3. Component library abstraction
  4. Advanced performance optimizations

Troubleshooting

“Function not defined” errors

  • Check script load order in HTML
  • Verify <script> tags are at end of <body>
  • Confirm module file path is correct

Tooltips not appearing

  • Check for CSS conflicts in _sass/_components.scss
  • Verify data-tech attribute format: “name description”
  • Inspect tooltip positioning logic for screen edge issues

Language switching doesn’t work

  • Verify pathMap configuration in inline script
  • Check browser localStorage for preferredLanguage
  • Ensure both EN and ES pages exist at mapped paths

Mobile menu not opening

  • Check ARIA attributes (aria-expanded, aria-controls)
  • Verify mobile overlay CSS in _sass/_layout.scss
  • Test on actual mobile device (not just browser DevTools)

Contact & Support

Project: Brandon JP Lambert Portfolio Repository: https://github.com/bjpl/bjpl.github.io Issues: Report via GitHub Issues Last Refactored: October 8, 2025 (Plan B technical debt reduction)


References

Related Documentation:

  • /docs/portfolio-review/03-technical-implementation.md - Technical review
  • /daily_reports/2025-10-08.md - Plan B execution report
  • /CLAUDE.md - Known Issues section (technical debt status)

Commits:

  • 3af9e27 - Extract JavaScript to modules (Oct 8, 2025)
  • 9f759f7 - Extract CSS from ai-projects.html (Oct 8, 2025)
  • 79db8c4 - Navigation deduplication & language switcher (Oct 8, 2025)

Generated as part of October 8, 2025 documentation updates.