185 lines
5.9 KiB
Markdown
185 lines
5.9 KiB
Markdown
|
|
# OxJS Codebase Analysis
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
OxJS is a JavaScript UI framework created around 2008, predating modern JavaScript build tools and module systems. It uses a custom build system and loading mechanism that was innovative for its time but needs modernization.
|
||
|
|
|
||
|
|
## Current Architecture
|
||
|
|
|
||
|
|
### 1. Module Structure
|
||
|
|
The codebase is organized into distinct modules:
|
||
|
|
- **Ox**: Core library with utilities (Array, String, Math, Type, etc.)
|
||
|
|
- **UI**: User interface components and themes
|
||
|
|
- **Geo**: Geographic utilities
|
||
|
|
- **Image**: Image manipulation utilities
|
||
|
|
- **Unicode**: Unicode utilities
|
||
|
|
|
||
|
|
Each module follows the pattern:
|
||
|
|
```
|
||
|
|
source/
|
||
|
|
├── ModuleName/
|
||
|
|
│ ├── ModuleName.js (module loader)
|
||
|
|
│ ├── js/ (JavaScript files)
|
||
|
|
│ └── json/ (locale and config files)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Custom Import/Loading System
|
||
|
|
|
||
|
|
#### Core Loader (`source/Ox.js`)
|
||
|
|
- The framework uses a custom `Ox.load()` function instead of ES modules
|
||
|
|
- Loading process:
|
||
|
|
1. Detects script path from `<script>` tag
|
||
|
|
2. Loads `Ox/json/Ox.json` manifest file
|
||
|
|
3. Sequentially loads script groups in dependency order
|
||
|
|
4. Supports dev (individual files) and min (bundled) modes
|
||
|
|
|
||
|
|
#### Module Loading Pattern
|
||
|
|
```javascript
|
||
|
|
// Usage in applications
|
||
|
|
Ox.load('UI', function() {
|
||
|
|
// Module is loaded, can use Ox.UI
|
||
|
|
});
|
||
|
|
|
||
|
|
// Module definition pattern
|
||
|
|
Ox.load.ModuleName = function(options, callback) {
|
||
|
|
// Module initialization code
|
||
|
|
callback(true); // success
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Build System (`tools/build/build.py`)
|
||
|
|
|
||
|
|
The Python build script performs several tasks:
|
||
|
|
|
||
|
|
#### Core Processing (`Ox` module)
|
||
|
|
1. **Dependency ordering**: Files are loaded in specific groups to handle dependencies
|
||
|
|
- Group 1: `Core.js` (defines Ox object)
|
||
|
|
- Group 2: `Function.js`, `Polyfill.js`
|
||
|
|
- Group 3: `Array.js`, `String.js`, `Type.js`
|
||
|
|
- Group 4: `Collection.js`, `Math.js`
|
||
|
|
- Remaining files loaded alphabetically
|
||
|
|
|
||
|
|
2. **Version injection**: Replaces `Ox.VERSION` placeholder
|
||
|
|
3. **Locale aggregation**: Collects all locale files into `Ox.LOCALES`
|
||
|
|
4. **Minification**: Uses `ox.js.minify()` to create compressed version
|
||
|
|
|
||
|
|
#### UI Module Processing
|
||
|
|
1. **Theme handling**:
|
||
|
|
- Reads theme data from `themes/*/json/theme.jsonc`
|
||
|
|
- Generates theme-specific CSS by replacing variables
|
||
|
|
- Creates theme-specific SVG files
|
||
|
|
|
||
|
|
2. **Asset management**:
|
||
|
|
- SVG files are embedded as strings in `ui_images`
|
||
|
|
- PNG files are copied to build directories
|
||
|
|
- CSS imports are dynamically generated
|
||
|
|
|
||
|
|
3. **File bundling**:
|
||
|
|
- All UI JavaScript files are concatenated into `UI/js/UI.js`
|
||
|
|
- Creates `UI/json/UI.json` manifest with file lists
|
||
|
|
|
||
|
|
#### Output Structure
|
||
|
|
Creates two build directories:
|
||
|
|
- `dev/`: Development version with symlinks to source files
|
||
|
|
- `min/`: Minified production version with concatenated files
|
||
|
|
|
||
|
|
### 4. Key Patterns and Conventions
|
||
|
|
|
||
|
|
#### No External Dependencies
|
||
|
|
- jQuery is bundled but loaded separately
|
||
|
|
- No npm packages or node_modules
|
||
|
|
- All dependencies are included in source
|
||
|
|
|
||
|
|
#### Global Namespace
|
||
|
|
- Everything hangs off the global `Ox` object
|
||
|
|
- No module-level scope isolation
|
||
|
|
- Methods are attached directly to `Ox` or `Ox.ModuleName`
|
||
|
|
|
||
|
|
#### Custom JSON with Comments (JSONC)
|
||
|
|
- Uses `.jsonc` files that support comments
|
||
|
|
- Custom parser in build process
|
||
|
|
|
||
|
|
#### Dynamic Loading
|
||
|
|
- Modules can be loaded on-demand
|
||
|
|
- Supports conditional loading based on options
|
||
|
|
- Locale files loaded lazily
|
||
|
|
|
||
|
|
## Challenges for ES Module Migration
|
||
|
|
|
||
|
|
### 1. Circular Dependencies
|
||
|
|
The current load order suggests potential circular dependencies that need careful handling.
|
||
|
|
|
||
|
|
### 2. Global State
|
||
|
|
Heavy reliance on global `Ox` object and sequential initialization.
|
||
|
|
|
||
|
|
### 3. Dynamic Module Loading
|
||
|
|
The `Ox.load()` pattern allows runtime module loading which differs from ES module static imports.
|
||
|
|
|
||
|
|
### 4. Build Process Integration
|
||
|
|
The Python build script handles many transformations that would need webpack/rollup equivalents.
|
||
|
|
|
||
|
|
### 5. Theme and Asset Processing
|
||
|
|
Complex CSS variable substitution and SVG processing needs modern build tool equivalents.
|
||
|
|
|
||
|
|
### 6. Browser Compatibility
|
||
|
|
Current system supports very old browsers; ES modules require modern browser support.
|
||
|
|
|
||
|
|
## Migration Strategy Considerations
|
||
|
|
|
||
|
|
### Phase 1: Preparation
|
||
|
|
- Add package.json and npm infrastructure
|
||
|
|
- Set up modern build tooling (webpack/rollup/vite)
|
||
|
|
- Create comprehensive test suite
|
||
|
|
|
||
|
|
### Phase 2: Module Conversion
|
||
|
|
- Convert individual files to ES modules
|
||
|
|
- Maintain backward compatibility layer
|
||
|
|
- Create barrel exports for each module
|
||
|
|
|
||
|
|
### Phase 3: Build System
|
||
|
|
- Replace Python build with npm scripts
|
||
|
|
- Implement CSS/SVG processing with PostCSS/webpack
|
||
|
|
- Set up development and production builds
|
||
|
|
|
||
|
|
### Phase 4: Distribution
|
||
|
|
- Publish to npm
|
||
|
|
- Support both ES modules and UMD builds
|
||
|
|
- Maintain script tag compatibility
|
||
|
|
|
||
|
|
## Inline Test System
|
||
|
|
|
||
|
|
OxJS has a unique inline test system integrated with its documentation:
|
||
|
|
|
||
|
|
### Test Format
|
||
|
|
Tests are embedded directly in documentation comments:
|
||
|
|
```javascript
|
||
|
|
/*@
|
||
|
|
My.foo <f> Returns an item's bar per baz
|
||
|
|
(item) -> <n> Bar per baz, or NaN
|
||
|
|
item <o> Any item
|
||
|
|
> My.foo({bar: 1, baz: 10})
|
||
|
|
0.1
|
||
|
|
> My.foo({})
|
||
|
|
NaN
|
||
|
|
@*/
|
||
|
|
```
|
||
|
|
|
||
|
|
### Test Execution
|
||
|
|
- `Ox.doc()` parses documentation and extracts test statements
|
||
|
|
- `Ox.test()` runs the tests and compares actual vs expected results
|
||
|
|
- Tests can be synchronous or asynchronous (using callbacks)
|
||
|
|
- Test results include pass/fail status and actual values
|
||
|
|
|
||
|
|
### Benefits
|
||
|
|
- Tests serve as executable documentation
|
||
|
|
- Examples are guaranteed to be accurate
|
||
|
|
- No separate test files needed for basic unit tests
|
||
|
|
- Human-readable format
|
||
|
|
|
||
|
|
## Key Files to Study
|
||
|
|
1. `source/Ox.js` - Core loader implementation
|
||
|
|
2. `source/Ox/js/Core.js` - Module loading logic
|
||
|
|
3. `source/Ox/js/JavaScript.js` - Documentation parser and test runner
|
||
|
|
4. `tools/build/build.py` - Build process details
|
||
|
|
5. `source/UI/UI.js` - Module initialization pattern
|
||
|
|
6. `examples/documentation/oxdoc_tutorial/js/example.js` - Documentation format examples
|
||
|
|
7. `index.js` - Main entry point usage
|