Fix code quality violations for publish

Remove unused blade settings pages not linked from UI
Convert remaining frontend pages to SPA actions
Convert settings user_settings and general to SPA actions
Convert settings profile pages to SPA actions
Convert contacts and projects add/edit pages to SPA actions
Convert clients add/edit page to SPA action with loading pattern
Refactor component scoped IDs from $id to $sid
Fix jqhtml comment syntax and implement universal error component system
Update all application code to use new unified error system
Remove all backwards compatibility - unified error system complete
Phase 5: Remove old response classes
Phase 3-4: Ajax response handler sends new format, old helpers deprecated
Phase 2: Add client-side unified error foundation
Phase 1: Add server-side unified error foundation
Add unified Ajax error response system with constants

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-21 04:35:01 +00:00
parent 081fc0b88e
commit 78553d4edf
899 changed files with 8887 additions and 7868 deletions

View File

@@ -27,7 +27,7 @@
- Access component methods via `this.methodName()`
### Attribute System
- `$id="name"``id="name:_cid"` (component-scoped ID)
- `$sid="name"``id="name:_cid"` (component-scoped ID)
- `$attr="value"``data-attr="value"` (data attributes)
- `@click="handler"` → jQuery event binding to component method
- `@submit.prevent="handler"` → Event with preventDefault
@@ -217,7 +217,7 @@ class UserCard extends Jqhtml_Component {
- `this._ready_state` - Lifecycle phase (0=created, 1=rendering, 2=creating, 3=loading, 4=ready)
### DOM Access Methods
- `this.$id('name')` - Get element by scoped ID (returns jQuery object)
- `this.$sid('name')` - Get element by scoped ID (returns jQuery object)
- `this.$child('name')` - Get child component by name
- `this.$children()` - Get all direct child components
- `this.$parent()` - Get parent component
@@ -260,11 +260,11 @@ class CustomInput extends Component {
val(value) {
if (arguments.length === 0) {
// Getter - return processed value
return this.parse_value(this.$id('input').val());
return this.parse_value(this.$sid('input').val());
} else {
// Setter - validate and set
if (this.validate(value)) {
this.$id('input').val(this.format_value(value));
this.$sid('input').val(this.format_value(value));
this.data.value = value;
}
return this.$; // Maintain jQuery chaining

20
node_modules/@jqhtml/core/README.md generated vendored
View File

@@ -132,7 +132,7 @@ If you need to show different DOM states before and after loading, use these pat
class DataComponent extends Component {
async on_create() {
// Set loading state in the DOM during create phase
this.$id('status').addClass('loading').text('Loading...');
this.$sid('status').addClass('loading').text('Loading...');
}
async on_load() {
@@ -142,8 +142,8 @@ class DataComponent extends Component {
async on_ready() {
// Update DOM after data is loaded
this.$id('status').removeClass('loading').text('Loaded');
this.$id('username').text(this.data.user.name);
this.$sid('status').removeClass('loading').text('Loaded');
this.$sid('username').text(this.data.user.name);
}
}
```
@@ -153,12 +153,12 @@ class DataComponent extends Component {
class BadComponent extends Component {
async on_load() {
// ❌ WRONG - DOM modification in load()
this.$id('status').text('Loading...'); // VIOLATION!
this.$sid('status').text('Loading...'); // VIOLATION!
this.data.user = await fetch('/api/user').then(r => r.json());
// ❌ WRONG - More DOM modification
this.$id('status').text('Loaded'); // VIOLATION!
this.$sid('status').text('Loaded'); // VIOLATION!
}
}
```
@@ -261,9 +261,9 @@ class TabsComponent extends Component {
selectTab(tabId) {
// Use $id() for scoped selection
this.$id('tab1').removeClass('active');
this.$id('tab2').removeClass('active');
this.$id(tabId).addClass('active');
this.$sid('tab1').removeClass('active');
this.$sid('tab2').removeClass('active');
this.$sid(tabId).addClass('active');
}
}
```
@@ -300,7 +300,7 @@ JQHTML has specific rules for attribute quoting and value passing:
- **@ Event attributes**: MUST be unquoted (pass function references)
Example: `@click=this.handleClick`
- **$ Data attributes**: Can be quoted OR unquoted (flexible)
Example: `$id="my-id"` or `$data=this.complexObject`
Example: `$sid="my-id"` or `$data=this.complexObject`
- **Regular HTML attributes**: MUST be quoted (strings only)
Example: `class="container <%= this.args.theme %>"`
@@ -375,7 +375,7 @@ $('#user-profile').component().on('ready', (component) => {
console.log('User data:', component.data.user);
// Safe to access all DOM elements
component.$id('email').addClass('verified');
component.$sid('email').addClass('verified');
});
```

0
node_modules/@jqhtml/core/dist/component-registry.d.ts generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/component-registry.d.ts.map generated vendored Executable file → Normal file
View File

28
node_modules/@jqhtml/core/dist/component.d.ts generated vendored Executable file → Normal file
View File

@@ -193,6 +193,17 @@ export declare class Jqhtml_Component {
on_load(): Promise<void>;
on_ready(): Promise<void>;
on_stop(): void | Promise<void>;
/**
* Optional: Override cache key generation
*
* By default, cache keys are generated from component name + args.
* Override this method to provide a custom cache key for this component instance.
*
* If this method throws an error, caching will be disabled for this component.
*
* @returns Custom cache key string (will be prefixed with component name)
*/
cache_id?(): string;
/**
* Should component re-render after load?
* By default, only re-renders if data has changed
@@ -231,9 +242,9 @@ export declare class Jqhtml_Component {
* Searches for elements with id="local_id:THIS_COMPONENT_CID"
*
* Example:
* Template: <button $id="save_btn">Save</button>
* Rendered: <button id="save_btn:abc123" data-id="save_btn">Save</button>
* Access: this.$id('save_btn') // Returns jQuery element
* Template: <button $sid="save_btn">Save</button>
* Rendered: <button id="save_btn:abc123" data-sid="save_btn">Save</button>
* Access: this.$sid('save_btn') // Returns jQuery element
*
* Performance: Uses native document.getElementById() when component is in DOM,
* falls back to jQuery.find() for components not yet attached to DOM.
@@ -241,21 +252,24 @@ export declare class Jqhtml_Component {
* @param local_id The local ID (without _cid suffix)
* @returns jQuery element with id="local_id:_cid", or empty jQuery object if not found
*/
$id(local_id: string): any;
$sid(local_id: string): any;
/**
* Get component instance by scoped ID
*
* Convenience method that finds element by scoped ID and returns the component instance.
*
* Example:
* Template: <User_Card $id="active_user" />
* Access: const user = this.id('active_user'); // Returns User_Card instance
* Template: <User_Card $sid="active_user" />
* Access: const user = this.sid('active_user'); // Returns User_Card instance
* user.data.name // Access component's data
*
* To get the scoped ID string itself:
* this.$sid('active_user').attr('id') // Returns "active_user:abc123xyz"
*
* @param local_id The local ID (without _cid suffix)
* @returns Component instance or null if not found or not a component
*/
id(local_id: string): Jqhtml_Component | null;
sid(local_id: string): Jqhtml_Component | null;
/**
* Get the component that instantiated this component (rendered it in their template)
* Returns null if component was created programmatically via $().component()

2
node_modules/@jqhtml/core/dist/component.d.ts.map generated vendored Executable file → Normal file
View File

@@ -1 +1 @@
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"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"}

0
node_modules/@jqhtml/core/dist/debug-entry.d.ts generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/debug-entry.d.ts.map generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/debug-overlay.d.ts generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/debug-overlay.d.ts.map generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/debug.d.ts generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/debug.d.ts.map generated vendored Executable file → Normal file
View File

130
node_modules/@jqhtml/core/dist/index.cjs generated vendored Executable file → Normal file
View File

@@ -499,7 +499,7 @@ function process_tag_to_html(instruction, html, tagElements, components, context
if (key === 'id' && tid) {
// Special handling for id attribute - scope to parent component's _cid
// This is for regular id="foo" attributes that need scoping (rare case)
// Most scoping happens via $id attribute which becomes data-id
// Most scoping happens via $sid attribute which becomes data-sid
// Don't double-scope if already scoped (contains :)
if (typeof value === 'string' && value.includes(':')) {
html.push(` id="${value}"`);
@@ -549,13 +549,13 @@ function process_component_to_html(instruction, html, components, context) {
// Create element with tracking ID
html.push(`<${tagName} data-cid="${cid}"`);
// Handle id attributes for components
// The compiled code always generates both 'id' (scoped) and 'data-id' (base) for $id attributes
// The compiled code always generates both 'id' (scoped) and 'data-sid' (base) for $sid attributes
// We just pass through what the compiler gave us - NEVER regenerate
if (props['data-id']) {
const baseId = props['data-id'];
if (props['data-sid']) {
const baseId = props['data-sid'];
// The compiled code ALWAYS sets props['id'] with the correct scoped value
// Just use it directly - it already has the correct parent _cid baked in
html.push(` id="${props['id']}" data-id="${baseId}"`);
html.push(` id="${props['id']}" data-sid="${baseId}"`);
}
// Regular id passes through unchanged
else if (props['id']) {
@@ -1229,16 +1229,16 @@ class Jqhtml_Component {
// If id provided, delegate to child component
if (id) {
// First check if element with scoped ID exists
const $element = this.$id(id);
const $element = this.$sid(id);
if ($element.length === 0) {
throw new Error(`[JQHTML] render("${id}") - no such id.\n` +
`Component "${this.component_name()}" has no child element with $id="${id}".`);
`Component "${this.component_name()}" has no child element with $sid="${id}".`);
}
// Element exists, check if it's a component
const child = $element.data('_component');
if (!child) {
throw new Error(`[JQHTML] render("${id}") - element is not a component or does not have $redrawable attribute set.\n` +
`Element with $id="${id}" exists but is not initialized as a component.\n` +
`Element with $sid="${id}" exists but is not initialized as a component.\n` +
`Add $redrawable attribute or make it a proper component.`);
}
return child._render();
@@ -1459,15 +1459,15 @@ class Jqhtml_Component {
return;
// If id provided, delegate to child component
if (id) {
const $element = this.$id(id);
const $element = this.$sid(id);
if ($element.length === 0) {
throw new Error(`[JQHTML] render("${id}") - no such id.\n` +
`Component "${this.component_name()}" has no child element with $id="${id}".`);
`Component "${this.component_name()}" has no child element with $sid="${id}".`);
}
const child = $element.data('_component');
if (!child) {
throw new Error(`[JQHTML] render("${id}") - element is not a component or does not have $redrawable attribute set.\n` +
`Element with $id="${id}" exists but is not initialized as a component.\n` +
`Element with $sid="${id}" exists but is not initialized as a component.\n` +
`Add $redrawable attribute or make it a proper component.`);
}
return child.render();
@@ -1515,8 +1515,26 @@ class Jqhtml_Component {
// This happens after on_create() but before render, allowing instant first render with cached data
const { Load_Coordinator } = await Promise.resolve().then(function () { return loadCoordinator; });
const { Jqhtml_Local_Storage } = await Promise.resolve().then(function () { return localStorage$1; });
const { key: cache_key, uncacheable_property } = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
// If cache_key is null, args are not serializable - skip caching
// Check if component implements cache_id() for custom cache key
let cache_key = null;
let uncacheable_property;
if (typeof this.cache_id === 'function') {
try {
const custom_cache_id = this.cache_id();
cache_key = `${this.component_name()}::${String(custom_cache_id)}`;
}
catch (error) {
// cache_id() threw error - disable caching
uncacheable_property = 'cache_id()';
}
}
else {
// Use standard args-based cache key generation
const result = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
cache_key = result.key;
uncacheable_property = result.uncacheable_property;
}
// If cache_key is null, caching disabled
if (cache_key === null) {
// Set data-nocache attribute for debugging (shows which property prevented caching)
if (uncacheable_property) {
@@ -1574,8 +1592,25 @@ class Jqhtml_Component {
// Import coordinator and storage lazily to avoid circular dependency
const { Load_Coordinator } = await Promise.resolve().then(function () { return loadCoordinator; });
const { Jqhtml_Local_Storage } = await Promise.resolve().then(function () { return localStorage$1; });
// Generate cache key (same as deduplication key)
const { key: cache_key, uncacheable_property } = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
// Check if component implements cache_id() for custom cache key
let cache_key = null;
let uncacheable_property;
if (typeof this.cache_id === 'function') {
try {
const custom_cache_id = this.cache_id();
cache_key = `${this.component_name()}::${String(custom_cache_id)}`;
}
catch (error) {
// cache_id() threw error - disable caching
uncacheable_property = 'cache_id()';
}
}
else {
// Use standard args-based cache key generation
const result = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
cache_key = result.key;
uncacheable_property = result.uncacheable_property;
}
// If cache_key is null, args are not serializable - skip load deduplication and caching
if (cache_key === null) {
// Set data-nocache attribute for debugging (shows which property prevented caching)
@@ -1916,7 +1951,23 @@ class Jqhtml_Component {
if (args_changed) {
const { Load_Coordinator } = await Promise.resolve().then(function () { return loadCoordinator; });
const { Jqhtml_Local_Storage } = await Promise.resolve().then(function () { return localStorage$1; });
const { key: cache_key, uncacheable_property } = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
// Check if component implements cache_id() for custom cache key
let cache_key = null;
if (typeof this.cache_id === 'function') {
try {
const custom_cache_id = this.cache_id();
cache_key = `${this.component_name()}::${String(custom_cache_id)}`;
}
catch (error) {
// cache_id() threw error - disable caching
cache_key = null;
}
}
else {
// Use standard args-based cache key generation
const result = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
cache_key = result.key;
}
// Only use cache if args are serializable
if (cache_key !== null) {
const cached_data = Jqhtml_Local_Storage.get(cache_key);
@@ -1955,7 +2006,23 @@ class Jqhtml_Component {
if (data_changed && data_after_load !== '{}') {
const { Load_Coordinator } = await Promise.resolve().then(function () { return loadCoordinator; });
const { Jqhtml_Local_Storage } = await Promise.resolve().then(function () { return localStorage$1; });
const { key: cache_key, uncacheable_property } = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
// Check if component implements cache_id() for custom cache key
let cache_key = null;
if (typeof this.cache_id === 'function') {
try {
const custom_cache_id = this.cache_id();
cache_key = `${this.component_name()}::${String(custom_cache_id)}`;
}
catch (error) {
// cache_id() threw error - disable caching
cache_key = null;
}
}
else {
// Use standard args-based cache key generation
const result = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
cache_key = result.key;
}
// Only update cache if args are serializable
if (cache_key !== null) {
Jqhtml_Local_Storage.set(cache_key, this.data);
@@ -2166,9 +2233,9 @@ class Jqhtml_Component {
* Searches for elements with id="local_id:THIS_COMPONENT_CID"
*
* Example:
* Template: <button $id="save_btn">Save</button>
* Rendered: <button id="save_btn:abc123" data-id="save_btn">Save</button>
* Access: this.$id('save_btn') // Returns jQuery element
* Template: <button $sid="save_btn">Save</button>
* Rendered: <button id="save_btn:abc123" data-sid="save_btn">Save</button>
* Access: this.$sid('save_btn') // Returns jQuery element
*
* Performance: Uses native document.getElementById() when component is in DOM,
* falls back to jQuery.find() for components not yet attached to DOM.
@@ -2176,7 +2243,7 @@ class Jqhtml_Component {
* @param local_id The local ID (without _cid suffix)
* @returns jQuery element with id="local_id:_cid", or empty jQuery object if not found
*/
$id(local_id) {
$sid(local_id) {
const scopedId = `${local_id}:${this._cid}`;
// Try getElementById first (fast path - works when component is in DOM)
const el = document.getElementById(scopedId);
@@ -2184,7 +2251,7 @@ class Jqhtml_Component {
return $(el);
}
// Fallback: component not in DOM yet, search within component subtree
// This allows $id() to work on components before they're appended to body
// This allows $sid() to work on components before they're appended to body
// Must escape the ID because it contains ':' which jQuery treats as a pseudo-selector
return this.$.find(`#${$.escapeSelector(scopedId)}`);
}
@@ -2194,19 +2261,22 @@ class Jqhtml_Component {
* Convenience method that finds element by scoped ID and returns the component instance.
*
* Example:
* Template: <User_Card $id="active_user" />
* Access: const user = this.id('active_user'); // Returns User_Card instance
* Template: <User_Card $sid="active_user" />
* Access: const user = this.sid('active_user'); // Returns User_Card instance
* user.data.name // Access component's data
*
* To get the scoped ID string itself:
* this.$sid('active_user').attr('id') // Returns "active_user:abc123xyz"
*
* @param local_id The local ID (without _cid suffix)
* @returns Component instance or null if not found or not a component
*/
id(local_id) {
const element = this.$id(local_id);
sid(local_id) {
const element = this.$sid(local_id);
const component = element.data('_component');
// If no component found but element exists, warn developer
if (!component && element.length > 0) {
console.warn(`Component ${this.constructor.name} tried to call .id('${local_id}') - ` +
console.warn(`Component ${this.constructor.name} tried to call .sid('${local_id}') - ` +
`${local_id} exists, however, it is not a component or $redrawable. ` +
`Did you forget to add $redrawable to the tag?`);
}
@@ -2825,7 +2895,7 @@ function evaluate_expression(expression, component, locals = {}) {
args: component.args,
$: component.$,
// Component methods
$id: component.$id.bind(component),
$sid: component.$sid.bind(component),
// Locals (like $event)
...locals
};
@@ -2853,7 +2923,7 @@ function evaluate_handler(expression, component) {
// Otherwise treat as inline code
try {
return new Function('$event', `
const { data, args, $, emit, $id } = this;
const { data, args, $, emit, $sid } = this;
${expression}
`).bind(component);
}
@@ -4151,7 +4221,7 @@ function init(jQuery) {
}
}
// Version - will be replaced during build with actual version from package.json
const version = '2.2.217';
const version = '2.2.218';
// Default export with all functionality
const jqhtml = {
// Core

2
node_modules/@jqhtml/core/dist/index.cjs.map generated vendored Executable file → Normal file

File diff suppressed because one or more lines are too long

0
node_modules/@jqhtml/core/dist/index.d.ts generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/index.d.ts.map generated vendored Executable file → Normal file
View File

130
node_modules/@jqhtml/core/dist/index.js generated vendored Executable file → Normal file
View File

@@ -495,7 +495,7 @@ function process_tag_to_html(instruction, html, tagElements, components, context
if (key === 'id' && tid) {
// Special handling for id attribute - scope to parent component's _cid
// This is for regular id="foo" attributes that need scoping (rare case)
// Most scoping happens via $id attribute which becomes data-id
// Most scoping happens via $sid attribute which becomes data-sid
// Don't double-scope if already scoped (contains :)
if (typeof value === 'string' && value.includes(':')) {
html.push(` id="${value}"`);
@@ -545,13 +545,13 @@ function process_component_to_html(instruction, html, components, context) {
// Create element with tracking ID
html.push(`<${tagName} data-cid="${cid}"`);
// Handle id attributes for components
// The compiled code always generates both 'id' (scoped) and 'data-id' (base) for $id attributes
// The compiled code always generates both 'id' (scoped) and 'data-sid' (base) for $sid attributes
// We just pass through what the compiler gave us - NEVER regenerate
if (props['data-id']) {
const baseId = props['data-id'];
if (props['data-sid']) {
const baseId = props['data-sid'];
// The compiled code ALWAYS sets props['id'] with the correct scoped value
// Just use it directly - it already has the correct parent _cid baked in
html.push(` id="${props['id']}" data-id="${baseId}"`);
html.push(` id="${props['id']}" data-sid="${baseId}"`);
}
// Regular id passes through unchanged
else if (props['id']) {
@@ -1225,16 +1225,16 @@ class Jqhtml_Component {
// If id provided, delegate to child component
if (id) {
// First check if element with scoped ID exists
const $element = this.$id(id);
const $element = this.$sid(id);
if ($element.length === 0) {
throw new Error(`[JQHTML] render("${id}") - no such id.\n` +
`Component "${this.component_name()}" has no child element with $id="${id}".`);
`Component "${this.component_name()}" has no child element with $sid="${id}".`);
}
// Element exists, check if it's a component
const child = $element.data('_component');
if (!child) {
throw new Error(`[JQHTML] render("${id}") - element is not a component or does not have $redrawable attribute set.\n` +
`Element with $id="${id}" exists but is not initialized as a component.\n` +
`Element with $sid="${id}" exists but is not initialized as a component.\n` +
`Add $redrawable attribute or make it a proper component.`);
}
return child._render();
@@ -1455,15 +1455,15 @@ class Jqhtml_Component {
return;
// If id provided, delegate to child component
if (id) {
const $element = this.$id(id);
const $element = this.$sid(id);
if ($element.length === 0) {
throw new Error(`[JQHTML] render("${id}") - no such id.\n` +
`Component "${this.component_name()}" has no child element with $id="${id}".`);
`Component "${this.component_name()}" has no child element with $sid="${id}".`);
}
const child = $element.data('_component');
if (!child) {
throw new Error(`[JQHTML] render("${id}") - element is not a component or does not have $redrawable attribute set.\n` +
`Element with $id="${id}" exists but is not initialized as a component.\n` +
`Element with $sid="${id}" exists but is not initialized as a component.\n` +
`Add $redrawable attribute or make it a proper component.`);
}
return child.render();
@@ -1511,8 +1511,26 @@ class Jqhtml_Component {
// This happens after on_create() but before render, allowing instant first render with cached data
const { Load_Coordinator } = await Promise.resolve().then(function () { return loadCoordinator; });
const { Jqhtml_Local_Storage } = await Promise.resolve().then(function () { return localStorage$1; });
const { key: cache_key, uncacheable_property } = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
// If cache_key is null, args are not serializable - skip caching
// Check if component implements cache_id() for custom cache key
let cache_key = null;
let uncacheable_property;
if (typeof this.cache_id === 'function') {
try {
const custom_cache_id = this.cache_id();
cache_key = `${this.component_name()}::${String(custom_cache_id)}`;
}
catch (error) {
// cache_id() threw error - disable caching
uncacheable_property = 'cache_id()';
}
}
else {
// Use standard args-based cache key generation
const result = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
cache_key = result.key;
uncacheable_property = result.uncacheable_property;
}
// If cache_key is null, caching disabled
if (cache_key === null) {
// Set data-nocache attribute for debugging (shows which property prevented caching)
if (uncacheable_property) {
@@ -1570,8 +1588,25 @@ class Jqhtml_Component {
// Import coordinator and storage lazily to avoid circular dependency
const { Load_Coordinator } = await Promise.resolve().then(function () { return loadCoordinator; });
const { Jqhtml_Local_Storage } = await Promise.resolve().then(function () { return localStorage$1; });
// Generate cache key (same as deduplication key)
const { key: cache_key, uncacheable_property } = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
// Check if component implements cache_id() for custom cache key
let cache_key = null;
let uncacheable_property;
if (typeof this.cache_id === 'function') {
try {
const custom_cache_id = this.cache_id();
cache_key = `${this.component_name()}::${String(custom_cache_id)}`;
}
catch (error) {
// cache_id() threw error - disable caching
uncacheable_property = 'cache_id()';
}
}
else {
// Use standard args-based cache key generation
const result = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
cache_key = result.key;
uncacheable_property = result.uncacheable_property;
}
// If cache_key is null, args are not serializable - skip load deduplication and caching
if (cache_key === null) {
// Set data-nocache attribute for debugging (shows which property prevented caching)
@@ -1912,7 +1947,23 @@ class Jqhtml_Component {
if (args_changed) {
const { Load_Coordinator } = await Promise.resolve().then(function () { return loadCoordinator; });
const { Jqhtml_Local_Storage } = await Promise.resolve().then(function () { return localStorage$1; });
const { key: cache_key, uncacheable_property } = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
// Check if component implements cache_id() for custom cache key
let cache_key = null;
if (typeof this.cache_id === 'function') {
try {
const custom_cache_id = this.cache_id();
cache_key = `${this.component_name()}::${String(custom_cache_id)}`;
}
catch (error) {
// cache_id() threw error - disable caching
cache_key = null;
}
}
else {
// Use standard args-based cache key generation
const result = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
cache_key = result.key;
}
// Only use cache if args are serializable
if (cache_key !== null) {
const cached_data = Jqhtml_Local_Storage.get(cache_key);
@@ -1951,7 +2002,23 @@ class Jqhtml_Component {
if (data_changed && data_after_load !== '{}') {
const { Load_Coordinator } = await Promise.resolve().then(function () { return loadCoordinator; });
const { Jqhtml_Local_Storage } = await Promise.resolve().then(function () { return localStorage$1; });
const { key: cache_key, uncacheable_property } = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
// Check if component implements cache_id() for custom cache key
let cache_key = null;
if (typeof this.cache_id === 'function') {
try {
const custom_cache_id = this.cache_id();
cache_key = `${this.component_name()}::${String(custom_cache_id)}`;
}
catch (error) {
// cache_id() threw error - disable caching
cache_key = null;
}
}
else {
// Use standard args-based cache key generation
const result = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
cache_key = result.key;
}
// Only update cache if args are serializable
if (cache_key !== null) {
Jqhtml_Local_Storage.set(cache_key, this.data);
@@ -2162,9 +2229,9 @@ class Jqhtml_Component {
* Searches for elements with id="local_id:THIS_COMPONENT_CID"
*
* Example:
* Template: <button $id="save_btn">Save</button>
* Rendered: <button id="save_btn:abc123" data-id="save_btn">Save</button>
* Access: this.$id('save_btn') // Returns jQuery element
* Template: <button $sid="save_btn">Save</button>
* Rendered: <button id="save_btn:abc123" data-sid="save_btn">Save</button>
* Access: this.$sid('save_btn') // Returns jQuery element
*
* Performance: Uses native document.getElementById() when component is in DOM,
* falls back to jQuery.find() for components not yet attached to DOM.
@@ -2172,7 +2239,7 @@ class Jqhtml_Component {
* @param local_id The local ID (without _cid suffix)
* @returns jQuery element with id="local_id:_cid", or empty jQuery object if not found
*/
$id(local_id) {
$sid(local_id) {
const scopedId = `${local_id}:${this._cid}`;
// Try getElementById first (fast path - works when component is in DOM)
const el = document.getElementById(scopedId);
@@ -2180,7 +2247,7 @@ class Jqhtml_Component {
return $(el);
}
// Fallback: component not in DOM yet, search within component subtree
// This allows $id() to work on components before they're appended to body
// This allows $sid() to work on components before they're appended to body
// Must escape the ID because it contains ':' which jQuery treats as a pseudo-selector
return this.$.find(`#${$.escapeSelector(scopedId)}`);
}
@@ -2190,19 +2257,22 @@ class Jqhtml_Component {
* Convenience method that finds element by scoped ID and returns the component instance.
*
* Example:
* Template: <User_Card $id="active_user" />
* Access: const user = this.id('active_user'); // Returns User_Card instance
* Template: <User_Card $sid="active_user" />
* Access: const user = this.sid('active_user'); // Returns User_Card instance
* user.data.name // Access component's data
*
* To get the scoped ID string itself:
* this.$sid('active_user').attr('id') // Returns "active_user:abc123xyz"
*
* @param local_id The local ID (without _cid suffix)
* @returns Component instance or null if not found or not a component
*/
id(local_id) {
const element = this.$id(local_id);
sid(local_id) {
const element = this.$sid(local_id);
const component = element.data('_component');
// If no component found but element exists, warn developer
if (!component && element.length > 0) {
console.warn(`Component ${this.constructor.name} tried to call .id('${local_id}') - ` +
console.warn(`Component ${this.constructor.name} tried to call .sid('${local_id}') - ` +
`${local_id} exists, however, it is not a component or $redrawable. ` +
`Did you forget to add $redrawable to the tag?`);
}
@@ -2821,7 +2891,7 @@ function evaluate_expression(expression, component, locals = {}) {
args: component.args,
$: component.$,
// Component methods
$id: component.$id.bind(component),
$sid: component.$sid.bind(component),
// Locals (like $event)
...locals
};
@@ -2849,7 +2919,7 @@ function evaluate_handler(expression, component) {
// Otherwise treat as inline code
try {
return new Function('$event', `
const { data, args, $, emit, $id } = this;
const { data, args, $, emit, $sid } = this;
${expression}
`).bind(component);
}
@@ -4147,7 +4217,7 @@ function init(jQuery) {
}
}
// Version - will be replaced during build with actual version from package.json
const version = '2.2.217';
const version = '2.2.218';
// Default export with all functionality
const jqhtml = {
// Core

2
node_modules/@jqhtml/core/dist/index.js.map generated vendored Executable file → Normal file

File diff suppressed because one or more lines are too long

0
node_modules/@jqhtml/core/dist/instruction-processor.d.ts generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/instruction-processor.d.ts.map generated vendored Executable file → Normal file
View File

132
node_modules/@jqhtml/core/dist/jqhtml-core.esm.js generated vendored Executable file → Normal file
View File

@@ -1,5 +1,5 @@
/**
* JQHTML Core v2.2.217
* JQHTML Core v2.2.218
* (c) 2025 JQHTML Team
* Released under the MIT License
*/
@@ -500,7 +500,7 @@ function process_tag_to_html(instruction, html, tagElements, components, context
if (key === 'id' && tid) {
// Special handling for id attribute - scope to parent component's _cid
// This is for regular id="foo" attributes that need scoping (rare case)
// Most scoping happens via $id attribute which becomes data-id
// Most scoping happens via $sid attribute which becomes data-sid
// Don't double-scope if already scoped (contains :)
if (typeof value === 'string' && value.includes(':')) {
html.push(` id="${value}"`);
@@ -550,13 +550,13 @@ function process_component_to_html(instruction, html, components, context) {
// Create element with tracking ID
html.push(`<${tagName} data-cid="${cid}"`);
// Handle id attributes for components
// The compiled code always generates both 'id' (scoped) and 'data-id' (base) for $id attributes
// The compiled code always generates both 'id' (scoped) and 'data-sid' (base) for $sid attributes
// We just pass through what the compiler gave us - NEVER regenerate
if (props['data-id']) {
const baseId = props['data-id'];
if (props['data-sid']) {
const baseId = props['data-sid'];
// The compiled code ALWAYS sets props['id'] with the correct scoped value
// Just use it directly - it already has the correct parent _cid baked in
html.push(` id="${props['id']}" data-id="${baseId}"`);
html.push(` id="${props['id']}" data-sid="${baseId}"`);
}
// Regular id passes through unchanged
else if (props['id']) {
@@ -1230,16 +1230,16 @@ class Jqhtml_Component {
// If id provided, delegate to child component
if (id) {
// First check if element with scoped ID exists
const $element = this.$id(id);
const $element = this.$sid(id);
if ($element.length === 0) {
throw new Error(`[JQHTML] render("${id}") - no such id.\n` +
`Component "${this.component_name()}" has no child element with $id="${id}".`);
`Component "${this.component_name()}" has no child element with $sid="${id}".`);
}
// Element exists, check if it's a component
const child = $element.data('_component');
if (!child) {
throw new Error(`[JQHTML] render("${id}") - element is not a component or does not have $redrawable attribute set.\n` +
`Element with $id="${id}" exists but is not initialized as a component.\n` +
`Element with $sid="${id}" exists but is not initialized as a component.\n` +
`Add $redrawable attribute or make it a proper component.`);
}
return child._render();
@@ -1460,15 +1460,15 @@ class Jqhtml_Component {
return;
// If id provided, delegate to child component
if (id) {
const $element = this.$id(id);
const $element = this.$sid(id);
if ($element.length === 0) {
throw new Error(`[JQHTML] render("${id}") - no such id.\n` +
`Component "${this.component_name()}" has no child element with $id="${id}".`);
`Component "${this.component_name()}" has no child element with $sid="${id}".`);
}
const child = $element.data('_component');
if (!child) {
throw new Error(`[JQHTML] render("${id}") - element is not a component or does not have $redrawable attribute set.\n` +
`Element with $id="${id}" exists but is not initialized as a component.\n` +
`Element with $sid="${id}" exists but is not initialized as a component.\n` +
`Add $redrawable attribute or make it a proper component.`);
}
return child.render();
@@ -1516,8 +1516,26 @@ class Jqhtml_Component {
// This happens after on_create() but before render, allowing instant first render with cached data
const { Load_Coordinator } = await Promise.resolve().then(function () { return loadCoordinator; });
const { Jqhtml_Local_Storage } = await Promise.resolve().then(function () { return localStorage$1; });
const { key: cache_key, uncacheable_property } = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
// If cache_key is null, args are not serializable - skip caching
// Check if component implements cache_id() for custom cache key
let cache_key = null;
let uncacheable_property;
if (typeof this.cache_id === 'function') {
try {
const custom_cache_id = this.cache_id();
cache_key = `${this.component_name()}::${String(custom_cache_id)}`;
}
catch (error) {
// cache_id() threw error - disable caching
uncacheable_property = 'cache_id()';
}
}
else {
// Use standard args-based cache key generation
const result = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
cache_key = result.key;
uncacheable_property = result.uncacheable_property;
}
// If cache_key is null, caching disabled
if (cache_key === null) {
// Set data-nocache attribute for debugging (shows which property prevented caching)
if (uncacheable_property) {
@@ -1575,8 +1593,25 @@ class Jqhtml_Component {
// Import coordinator and storage lazily to avoid circular dependency
const { Load_Coordinator } = await Promise.resolve().then(function () { return loadCoordinator; });
const { Jqhtml_Local_Storage } = await Promise.resolve().then(function () { return localStorage$1; });
// Generate cache key (same as deduplication key)
const { key: cache_key, uncacheable_property } = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
// Check if component implements cache_id() for custom cache key
let cache_key = null;
let uncacheable_property;
if (typeof this.cache_id === 'function') {
try {
const custom_cache_id = this.cache_id();
cache_key = `${this.component_name()}::${String(custom_cache_id)}`;
}
catch (error) {
// cache_id() threw error - disable caching
uncacheable_property = 'cache_id()';
}
}
else {
// Use standard args-based cache key generation
const result = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
cache_key = result.key;
uncacheable_property = result.uncacheable_property;
}
// If cache_key is null, args are not serializable - skip load deduplication and caching
if (cache_key === null) {
// Set data-nocache attribute for debugging (shows which property prevented caching)
@@ -1917,7 +1952,23 @@ class Jqhtml_Component {
if (args_changed) {
const { Load_Coordinator } = await Promise.resolve().then(function () { return loadCoordinator; });
const { Jqhtml_Local_Storage } = await Promise.resolve().then(function () { return localStorage$1; });
const { key: cache_key, uncacheable_property } = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
// Check if component implements cache_id() for custom cache key
let cache_key = null;
if (typeof this.cache_id === 'function') {
try {
const custom_cache_id = this.cache_id();
cache_key = `${this.component_name()}::${String(custom_cache_id)}`;
}
catch (error) {
// cache_id() threw error - disable caching
cache_key = null;
}
}
else {
// Use standard args-based cache key generation
const result = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
cache_key = result.key;
}
// Only use cache if args are serializable
if (cache_key !== null) {
const cached_data = Jqhtml_Local_Storage.get(cache_key);
@@ -1956,7 +2007,23 @@ class Jqhtml_Component {
if (data_changed && data_after_load !== '{}') {
const { Load_Coordinator } = await Promise.resolve().then(function () { return loadCoordinator; });
const { Jqhtml_Local_Storage } = await Promise.resolve().then(function () { return localStorage$1; });
const { key: cache_key, uncacheable_property } = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
// Check if component implements cache_id() for custom cache key
let cache_key = null;
if (typeof this.cache_id === 'function') {
try {
const custom_cache_id = this.cache_id();
cache_key = `${this.component_name()}::${String(custom_cache_id)}`;
}
catch (error) {
// cache_id() threw error - disable caching
cache_key = null;
}
}
else {
// Use standard args-based cache key generation
const result = Load_Coordinator.generate_invocation_key(this.component_name(), this.args);
cache_key = result.key;
}
// Only update cache if args are serializable
if (cache_key !== null) {
Jqhtml_Local_Storage.set(cache_key, this.data);
@@ -2167,9 +2234,9 @@ class Jqhtml_Component {
* Searches for elements with id="local_id:THIS_COMPONENT_CID"
*
* Example:
* Template: <button $id="save_btn">Save</button>
* Rendered: <button id="save_btn:abc123" data-id="save_btn">Save</button>
* Access: this.$id('save_btn') // Returns jQuery element
* Template: <button $sid="save_btn">Save</button>
* Rendered: <button id="save_btn:abc123" data-sid="save_btn">Save</button>
* Access: this.$sid('save_btn') // Returns jQuery element
*
* Performance: Uses native document.getElementById() when component is in DOM,
* falls back to jQuery.find() for components not yet attached to DOM.
@@ -2177,7 +2244,7 @@ class Jqhtml_Component {
* @param local_id The local ID (without _cid suffix)
* @returns jQuery element with id="local_id:_cid", or empty jQuery object if not found
*/
$id(local_id) {
$sid(local_id) {
const scopedId = `${local_id}:${this._cid}`;
// Try getElementById first (fast path - works when component is in DOM)
const el = document.getElementById(scopedId);
@@ -2185,7 +2252,7 @@ class Jqhtml_Component {
return $(el);
}
// Fallback: component not in DOM yet, search within component subtree
// This allows $id() to work on components before they're appended to body
// This allows $sid() to work on components before they're appended to body
// Must escape the ID because it contains ':' which jQuery treats as a pseudo-selector
return this.$.find(`#${$.escapeSelector(scopedId)}`);
}
@@ -2195,19 +2262,22 @@ class Jqhtml_Component {
* Convenience method that finds element by scoped ID and returns the component instance.
*
* Example:
* Template: <User_Card $id="active_user" />
* Access: const user = this.id('active_user'); // Returns User_Card instance
* Template: <User_Card $sid="active_user" />
* Access: const user = this.sid('active_user'); // Returns User_Card instance
* user.data.name // Access component's data
*
* To get the scoped ID string itself:
* this.$sid('active_user').attr('id') // Returns "active_user:abc123xyz"
*
* @param local_id The local ID (without _cid suffix)
* @returns Component instance or null if not found or not a component
*/
id(local_id) {
const element = this.$id(local_id);
sid(local_id) {
const element = this.$sid(local_id);
const component = element.data('_component');
// If no component found but element exists, warn developer
if (!component && element.length > 0) {
console.warn(`Component ${this.constructor.name} tried to call .id('${local_id}') - ` +
console.warn(`Component ${this.constructor.name} tried to call .sid('${local_id}') - ` +
`${local_id} exists, however, it is not a component or $redrawable. ` +
`Did you forget to add $redrawable to the tag?`);
}
@@ -2826,7 +2896,7 @@ function evaluate_expression(expression, component, locals = {}) {
args: component.args,
$: component.$,
// Component methods
$id: component.$id.bind(component),
$sid: component.$sid.bind(component),
// Locals (like $event)
...locals
};
@@ -2854,7 +2924,7 @@ function evaluate_handler(expression, component) {
// Otherwise treat as inline code
try {
return new Function('$event', `
const { data, args, $, emit, $id } = this;
const { data, args, $, emit, $sid } = this;
${expression}
`).bind(component);
}
@@ -4152,7 +4222,7 @@ function init(jQuery) {
}
}
// Version - will be replaced during build with actual version from package.json
const version = '2.2.217';
const version = '2.2.218';
// Default export with all functionality
const jqhtml = {
// Core

2
node_modules/@jqhtml/core/dist/jqhtml-core.esm.js.map generated vendored Executable file → Normal file

File diff suppressed because one or more lines are too long

0
node_modules/@jqhtml/core/dist/jqhtml-debug.esm.js generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/jqhtml-debug.esm.js.map generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/jquery-plugin.d.ts generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/jquery-plugin.d.ts.map generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/lifecycle-manager.d.ts generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/lifecycle-manager.d.ts.map generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/load-coordinator.d.ts generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/load-coordinator.d.ts.map generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/local-storage.d.ts generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/local-storage.d.ts.map generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/template-renderer.d.ts generated vendored Executable file → Normal file
View File

0
node_modules/@jqhtml/core/dist/template-renderer.d.ts.map generated vendored Executable file → Normal file
View File

2
node_modules/@jqhtml/core/package.json generated vendored Executable file → Normal file
View File

@@ -1,6 +1,6 @@
{
"name": "@jqhtml/core",
"version": "2.2.217",
"version": "2.2.218",
"description": "Core runtime library for JQHTML",
"type": "module",
"main": "./dist/index.js",