# AGENTS.md - AI Agent Configuration

## Project Overview

jQuery infinite scroll plugin with template rendering. Lightweight (~3KB minified), well-tested (16 tests), production-ready.

## Tech Stack

- jQuery 3.7.0
- jsRender 1.0.10 (template engine)
- Jest 29.7.0 (testing)
- Terser (minification)
- http-server (dev server)

## File Structure

```
├── jquery.infiniteScrollWithTemplate.js    # Main plugin (EDIT THIS)
├── jquery.infiniteScrollWithTemplate.min.js # Generated by build
├── jquery.infiniteScrollWithTemplate.d.ts   # TypeScript defs
├── package.json                             # Scripts & deps
├── README.md                                # Documentation
├── examples/
│   ├── index.html                          # Demo page
│   ├── data_sources.json                   # Demo data
│   └── generate                            # PHP data generator
├── tests/
│   ├── setup.js                            # Test config
│   └── jquery.infiniteScrollWithTemplate.test.js # 16 tests
├── scripts/
│   └── prepare-dist.js                     # Build script
└── .github/workflows/
    └── test.yml                            # CI/CD
```

## Coding Conventions

### JavaScript

- ES5 syntax (jQuery plugin pattern)
- Single quotes for strings
- 2-space indentation
- Semicolons required
- No trailing commas in objects/arrays
- camelCase for variables/functions
- PascalCase for constructors

### jQuery Plugin Pattern

```javascript
(function ($) {
  $.fn.pluginName = function (settings) {
    var $this = $(this);
    var opts = $.extend({}, defaults, settings);

    // Always return this for chaining
    return this;
  };

  $.fn.pluginName.defaults = { ... };
})(jQuery);
```

## Key Rules

### 1. Plugin Initialization

- Always validate required options (templateSelector, dataPath)
- Return jQuery object for chaining
- Use namespace for event handlers: `.infiniteTemplate_` + random string

### 2. AJAX Data Loading

- Build URLs with `buildUrl(baseUrl, page)` function
- Handle both absolute and relative URLs
- Support query parameters via `opts.query`
- Add cache buster when `opts.preventCache` is true

### 3. Template Rendering

- Use jsRender: `$.templates(selector).render(data)`
- Merge `opts.templateHelpers` with each item
- Use DocumentFragment for performance (already implemented)

### 4. Callbacks

- `loadingCallback()` - before AJAX
- `loadedCallback()` - after AJAX (success or error)
- `zeroCallback()` - when no data on first page
- `errorCallback(error)` - on AJAX/JSON parse error

### 5. State Management

- `currentScrollPage` - track current page
- `scrollTriggered` - prevent duplicate requests
- `isFinished` - stop when no more data

## Testing

```bash
npm test              # Run 16 tests
npm run build         # Minify + create dist/
npm run dev           # Start dev server with auto-open
```

### Test Structure

- Use jest with jsdom environment
- Mock jQuery.ajax
- Test all callbacks
- Test URL building
- Test edge cases (empty data, JSON parse errors)

## Build Process

```bash
npm run build
# 1. Minify with terser (creates .min.js)
# 2. Run scripts/prepare-dist.js
#    - Creates dist/ folder
#    - Copies examples/ to dist/examples/
#    - Copies plugin files to dist/
```

## Important Patterns

### Scroll Detection

```javascript
$(window).on("scroll" + namespace, function () {
  if (
    $(this).scrollTop() >
      $(document.body).height() -
        $(window).height() * (opts.scrollThreshold || 2) &&
    !isFinished
  ) {
    triggerDataLoad();
  }
});
```

### Click Loading (Alternative)

```javascript
if (opts.loadSelector) {
  $(document).on("click" + namespace, opts.loadSelector, function () {
    triggerDataLoad();
  });
}
```

### JSON Parsing

```javascript
if (typeof result === "string") {
  try {
    result = JSON.parse(result);
  } catch (e) {
    // Handle error
  }
}
```

## Common Tasks

### Adding New Feature

1. Update `jquery.infiniteScrollWithTemplate.js`
2. Add option to `$.fn.infiniteTemplate.defaults`
3. Add tests in `tests/jquery.infiniteScrollWithTemplate.test.js`
4. Update README.md options table
5. Run `npm test` to verify

### Fixing Bug

1. Check console.error messages in plugin
2. Add test case that reproduces bug
3. Fix in main plugin file
4. Verify test passes
5. Run `npm run build` to update dist/

### Updating Documentation

- README.md: User-facing docs
- Code comments: Inline documentation
- AGENTS.md: This file (AI guidance)

## DO NOT

- Modify `jquery.infiniteScrollWithTemplate.min.js` directly (auto-generated)
- Use ES6+ syntax (ES5 only for jQuery compatibility)
- Remove event namespace (causes memory leaks)
- Forget to return `this` (breaks chaining)
- Use `==` instead of `===` for comparisons

## CI/CD

GitHub Actions runs on:

- Push to main/master/develop
- Pull requests to main/master/develop
- Tests on Node.js 16.x, 18.x, 20.x
- Runs: npm ci → npm test → npm run build

## Deployment

```bash
npm run build
# Deploy dist/ folder to hosting
```

## Notes

- examples/generate is PHP script (ignore IDE warnings)
- .vscode/settings.json excludes PHP linter for generate
- Online demo: https://www.palgle.com/jquery-infinite-with-template/examples/index.html
