@zolomedia/bifrost-client 1.7.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/L1_Foundation/L1_Foundation.js +13 -0
- package/L1_Foundation/bootstrap/bootstrap.js +11 -0
- package/L1_Foundation/bootstrap/bootstrap_hooks.js +123 -0
- package/L1_Foundation/bootstrap/bootstrap_index.js +15 -0
- package/L1_Foundation/bootstrap/bootstrap_logger.js +135 -0
- package/L1_Foundation/bootstrap/cdn_loader.js +217 -0
- package/L1_Foundation/bootstrap/module_registry.js +102 -0
- package/L1_Foundation/bootstrap/prism_loader.js +164 -0
- package/L1_Foundation/config/client_config.js +110 -0
- package/L1_Foundation/config/config.js +7 -0
- package/L1_Foundation/connection/connection.js +8 -0
- package/L1_Foundation/connection/websocket_connection.js +122 -0
- package/L1_Foundation/constants/bifrost_constants.js +284 -0
- package/L1_Foundation/constants/constants.js +7 -0
- package/L1_Foundation/logger/logger.js +10 -0
- package/L2_Handling/L2_Handling.js +15 -0
- package/L2_Handling/cache/cache.js +22 -0
- package/L2_Handling/cache/cache_constants.js +69 -0
- package/L2_Handling/cache/orchestration/cache_manager.js +299 -0
- package/L2_Handling/cache/orchestration/cache_orchestrator.js +260 -0
- package/L2_Handling/cache/orchestration/orchestration.js +12 -0
- package/L2_Handling/cache/storage/session_manager.js +289 -0
- package/L2_Handling/cache/storage/storage.js +10 -0
- package/L2_Handling/cache/storage/storage_manager.js +590 -0
- package/L2_Handling/display/composite/composite.js +13 -0
- package/L2_Handling/display/composite/dashboard_renderer.js +221 -0
- package/L2_Handling/display/composite/swiper_renderer.js +564 -0
- package/L2_Handling/display/composite/terminal_renderer.js +922 -0
- package/L2_Handling/display/composite/wizard_conditional_renderer.js +274 -0
- package/L2_Handling/display/display.js +30 -0
- package/L2_Handling/display/feedback/feedback.js +11 -0
- package/L2_Handling/display/feedback/progressbar_renderer.js +418 -0
- package/L2_Handling/display/feedback/spinner_renderer.js +246 -0
- package/L2_Handling/display/inputs/button_renderer.js +634 -0
- package/L2_Handling/display/inputs/form_renderer.js +583 -0
- package/L2_Handling/display/inputs/input_renderer.js +658 -0
- package/L2_Handling/display/inputs/inputs.js +12 -0
- package/L2_Handling/display/navigation/menu_renderer.js +206 -0
- package/L2_Handling/display/navigation/navigation.js +11 -0
- package/L2_Handling/display/navigation/navigation_renderer.js +703 -0
- package/L2_Handling/display/orchestration/orchestration.js +11 -0
- package/L2_Handling/display/orchestration/renderer.js +430 -0
- package/L2_Handling/display/orchestration/zdisplay_orchestrator.js +1759 -0
- package/L2_Handling/display/outputs/alert_renderer.js +161 -0
- package/L2_Handling/display/outputs/audio_renderer.js +94 -0
- package/L2_Handling/display/outputs/card_renderer.js +229 -0
- package/L2_Handling/display/outputs/code_renderer.js +66 -0
- package/L2_Handling/display/outputs/dl_renderer.js +131 -0
- package/L2_Handling/display/outputs/header_renderer.js +162 -0
- package/L2_Handling/display/outputs/icon_renderer.js +107 -0
- package/L2_Handling/display/outputs/image_renderer.js +145 -0
- package/L2_Handling/display/outputs/list_renderer.js +190 -0
- package/L2_Handling/display/outputs/outputs.js +19 -0
- package/L2_Handling/display/outputs/table_renderer.js +765 -0
- package/L2_Handling/display/outputs/text_renderer.js +818 -0
- package/L2_Handling/display/outputs/typography_renderer.js +293 -0
- package/L2_Handling/display/outputs/video_renderer.js +116 -0
- package/L2_Handling/display/primitives/document_structure_primitives.js +319 -0
- package/L2_Handling/display/primitives/form_primitives.js +526 -0
- package/L2_Handling/display/primitives/generic_containers.js +109 -0
- package/L2_Handling/display/primitives/interactive_primitives.js +305 -0
- package/L2_Handling/display/primitives/link_primitives.js +552 -0
- package/L2_Handling/display/primitives/lists_primitives.js +262 -0
- package/L2_Handling/display/primitives/media_primitives.js +383 -0
- package/L2_Handling/display/primitives/primitives.js +19 -0
- package/L2_Handling/display/primitives/semantic_element_primitive.js +226 -0
- package/L2_Handling/display/primitives/table_primitives.js +528 -0
- package/L2_Handling/display/primitives/typography_primitives.js +175 -0
- package/L2_Handling/display/specialized/input_request_renderer.js +467 -0
- package/L2_Handling/display/specialized/specialized.js +10 -0
- package/L2_Handling/hooks/hooks.js +9 -0
- package/L2_Handling/hooks/menu_integration.js +57 -0
- package/L2_Handling/hooks/widget_hook_manager.js +292 -0
- package/L2_Handling/message/message.js +8 -0
- package/L2_Handling/message/message_handler.js +701 -0
- package/L2_Handling/navigation/navigation.js +8 -0
- package/L2_Handling/navigation/navigation_manager.js +403 -0
- package/L2_Handling/zhooks/features/cache_live.js +287 -0
- package/L2_Handling/zhooks/features/crumbs_live.js +292 -0
- package/L2_Handling/zhooks/zhooks_manager.js +65 -0
- package/L2_Handling/zvaf/zvaf.js +8 -0
- package/L2_Handling/zvaf/zvaf_manager.js +334 -0
- package/L3_Abstraction/L3_Abstraction.js +12 -0
- package/L3_Abstraction/orchestrator/container_unwrapper.js +101 -0
- package/L3_Abstraction/orchestrator/group_renderer.js +698 -0
- package/L3_Abstraction/orchestrator/input_event_handler.js +797 -0
- package/L3_Abstraction/orchestrator/metadata_processor.js +249 -0
- package/L3_Abstraction/orchestrator/navbar_builder.js +201 -0
- package/L3_Abstraction/orchestrator/orchestrator.js +13 -0
- package/L3_Abstraction/orchestrator/wizard_gate_handler.js +360 -0
- package/L3_Abstraction/renderer/renderer.js +1 -0
- package/L3_Abstraction/session/session.js +1 -0
- package/L4_Orchestration/L4_Orchestration.js +11 -0
- package/L4_Orchestration/client/client.js +1 -0
- package/L4_Orchestration/facade/facade.js +9 -0
- package/L4_Orchestration/facade/manager_registry.js +118 -0
- package/L4_Orchestration/facade/renderer_registry.js +274 -0
- package/L4_Orchestration/lifecycle/asset_loader.js +255 -0
- package/L4_Orchestration/lifecycle/initializer.js +135 -0
- package/L4_Orchestration/lifecycle/lifecycle.js +8 -0
- package/L4_Orchestration/rendering/facade.js +94 -0
- package/L4_Orchestration/rendering/rendering.js +7 -0
- package/LICENSE +21 -0
- package/README.md +82 -0
- package/bifrost_client.js +204 -0
- package/bifrost_core.js +1686 -0
- package/docs/ARCHITECTURE.md +111 -0
- package/docs/PROTOCOL.md +106 -0
- package/docs/RENDERERS.md +101 -0
- package/docs/SECURITY.md +92 -0
- package/package.json +24 -0
- package/syntax/prism-zconfig.js +41 -0
- package/syntax/prism-zenv.js +69 -0
- package/syntax/prism-zolo-theme.css +288 -0
- package/syntax/prism-zolo.js +380 -0
- package/syntax/prism-zschema.js +38 -0
- package/syntax/prism-zspark.js +25 -0
- package/syntax/prism-zui.js +68 -0
- package/zSys/accessibility/accessibility.js +10 -0
- package/zSys/accessibility/emoji_accessibility.js +173 -0
- package/zSys/dom/block_utils.js +122 -0
- package/zSys/dom/container_utils.js +370 -0
- package/zSys/dom/dom.js +13 -0
- package/zSys/dom/dom_utils.js +328 -0
- package/zSys/dom/encoding_utils.js +117 -0
- package/zSys/dom/style_utils.js +71 -0
- package/zSys/errors/error_display.js +299 -0
- package/zSys/errors/errors.js +10 -0
- package/zSys/theme/color_utils.js +274 -0
- package/zSys/theme/dark_mode_utils.js +272 -0
- package/zSys/theme/size_utils.js +256 -0
- package/zSys/theme/spacing_utils.js +405 -0
- package/zSys/theme/theme.js +14 -0
- package/zSys/theme/zbase.css +1735 -0
- package/zSys/theme/zbase_inject.js +161 -0
- package/zSys/theme/ztheme_utils.js +305 -0
- package/zSys/validation/error_boundary.js +201 -0
- package/zSys/validation/validation.js +11 -0
- package/zSys/validation/validation_utils.js +238 -0
- package/zSys/zSys.js +14 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prism.js language definition for zspark
|
|
3
|
+
* zSpark.*.zolo - Application entry point configuration
|
|
4
|
+
*
|
|
5
|
+
* Extends base 'zolo' language with file-type-specific patterns.
|
|
6
|
+
*
|
|
7
|
+
* Generated by zlsp/zlsp/generators/generate_prism_zolo.py
|
|
8
|
+
* DO NOT EDIT MANUALLY - regenerate with: python3 -m zlsp.generators.generate_prism_zolo
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
Prism.languages.zspark = Prism.languages.extend('zolo', {
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
// Insert value patterns BEFORE string-unquoted for priority
|
|
15
|
+
Prism.languages.insertBefore('zspark', 'string-unquoted', {
|
|
16
|
+
'zspark-zpath-value': {
|
|
17
|
+
pattern: /(?<=(?:zScrapath|zVaFolder|zSpace):\s*)[@~](?:\.[a-zA-Z0-9_./]+)?/,
|
|
18
|
+
alias: 'keyword',
|
|
19
|
+
lookbehind: true,
|
|
20
|
+
greedy: true,
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Support both ```zspark and ```zSpark code fences
|
|
25
|
+
Prism.languages.zSpark = Prism.languages.zspark;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prism.js language definition for zui
|
|
3
|
+
* zUI.*.zolo - User interface component files
|
|
4
|
+
*
|
|
5
|
+
* Extends base 'zolo' language with file-type-specific patterns.
|
|
6
|
+
*
|
|
7
|
+
* Generated by zlsp/zlsp/generators/generate_prism_zolo.py
|
|
8
|
+
* DO NOT EDIT MANUALLY - regenerate with: python3 -m zlsp.generators.generate_prism_zolo
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
Prism.languages.zui = Prism.languages.extend('zolo', {
|
|
12
|
+
'zui-special-root': {
|
|
13
|
+
pattern: /((?:^|\n)[ \t]*)(?:zMeta|zVaF)(?=\s*:)/m,
|
|
14
|
+
alias: 'function',
|
|
15
|
+
lookbehind: true,
|
|
16
|
+
},
|
|
17
|
+
'root-key': {
|
|
18
|
+
pattern: /(^|\n)([a-zA-Z][a-zA-Z0-9_]*)(?=\s*(?:\([^)]+\))?[*!^~]?:)/m,
|
|
19
|
+
alias: 'class-name',
|
|
20
|
+
lookbehind: true,
|
|
21
|
+
},
|
|
22
|
+
'property': {
|
|
23
|
+
pattern: /\b[a-zA-Z][a-zA-Z0-9_]*(?=\s*(?:\([^)]+\))?[*!]?:)/,
|
|
24
|
+
},
|
|
25
|
+
'prefix-modifier': {
|
|
26
|
+
pattern: /[\^~](?=[a-zA-Z][a-zA-Z0-9_]*\s*:)/,
|
|
27
|
+
alias: 'variable',
|
|
28
|
+
},
|
|
29
|
+
'suffix-modifier': {
|
|
30
|
+
pattern: /[*!](?=:)/,
|
|
31
|
+
alias: 'operator',
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Insert key patterns BEFORE 'property' for correct priority
|
|
36
|
+
Prism.languages.insertBefore('zui', 'property', {
|
|
37
|
+
'zrbac-key': {
|
|
38
|
+
pattern: /\bzRBAC(?=\s*:)/,
|
|
39
|
+
alias: 'constant',
|
|
40
|
+
},
|
|
41
|
+
'control-flow-key': {
|
|
42
|
+
pattern: /\bzWizard(?=\s*:)/,
|
|
43
|
+
alias: 'function',
|
|
44
|
+
},
|
|
45
|
+
'zsub-key': {
|
|
46
|
+
pattern: /\bzSub(?=\s*:)/,
|
|
47
|
+
alias: 'keyword',
|
|
48
|
+
},
|
|
49
|
+
'zui-element': {
|
|
50
|
+
pattern: /\b(?:zError|zWizard|zImage|zWarning|zSuccess|zH3|zDL|zTable|zSignal|zH0|zRange|zCheckbox|zInput|zH4|zBtn|zNavBar|zMD|zOL|zH6|zH1|zCode|zLink|zFunc|zCrumbs|zUL|zInfo|zH5|zH2|zURL|zText|zTerminal|zSelect)(?=\s*(?:\([^)]+\))?[*!]?:)/,
|
|
51
|
+
alias: 'function',
|
|
52
|
+
},
|
|
53
|
+
'metadata': {
|
|
54
|
+
pattern: /\b_z[A-Z][a-zA-Z]+(?=:)/,
|
|
55
|
+
alias: 'keyword',
|
|
56
|
+
},
|
|
57
|
+
'zui-element-property': {
|
|
58
|
+
pattern: /\b(?:action|alt_text|autocomplete|break_message|burst|caption|checked|color|columns|content|count|delay|disabled|every|format|full_page|href|id|indent|interactive|items|label|limit|max|maxlength|min|minlength|multi|multiple|name|offset|open_prompt|options|overwrite|parent|pattern|pause|placeholder|prefix|prompt|quality|readonly|rel|required|resolution|rows|selector|semantic|show|show_header|size|src|step|style|suffix|target|title|type|value|window|zAnchor)(?=\s*(?:\([^)]+\))?:)/,
|
|
59
|
+
alias: 'variable',
|
|
60
|
+
},
|
|
61
|
+
'zdispatch-event': {
|
|
62
|
+
pattern: /\b(?:zCRUD|zData|zDialog|zDispatch|zExport|zImport|zLogin|zMenu)(?=\s*(?:\([^)]+\))?[*!]?:)/,
|
|
63
|
+
alias: 'dispatch-event',
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Support both ```zui and ```zUI code fences
|
|
68
|
+
Prism.languages.zUI = Prism.languages.zui;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emoji Accessibility Module for Bifrost
|
|
3
|
+
*
|
|
4
|
+
* Provides ARIA labels for emojis to make them accessible to screen readers.
|
|
5
|
+
* Uses the CLDR-based emoji-a11y.en.json data file.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Lazy loading of emoji descriptions
|
|
9
|
+
* - Auto-wrap emojis with aria-label spans
|
|
10
|
+
* - Graceful fallback if data unavailable
|
|
11
|
+
* - Singleton pattern for efficient loading
|
|
12
|
+
*
|
|
13
|
+
* Phase 5: Bifrost ARIA Integration
|
|
14
|
+
* Author: zOS Framework
|
|
15
|
+
* Version: 1.0.0
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { escapeHtml } from '../dom/encoding_utils.js';
|
|
19
|
+
|
|
20
|
+
class EmojiAccessibility {
|
|
21
|
+
constructor(logger = console) {
|
|
22
|
+
this.logger = logger;
|
|
23
|
+
this.descriptions = null;
|
|
24
|
+
this.loading = null;
|
|
25
|
+
this.enabled = true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Lazy load emoji descriptions from JSON file.
|
|
30
|
+
*
|
|
31
|
+
* @returns {Promise<void>}
|
|
32
|
+
*/
|
|
33
|
+
async load() {
|
|
34
|
+
// Already loaded
|
|
35
|
+
if (this.descriptions) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Already loading (prevent duplicate requests)
|
|
40
|
+
if (this.loading) {
|
|
41
|
+
return this.loading;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Start loading
|
|
45
|
+
this.loading = (async () => {
|
|
46
|
+
try {
|
|
47
|
+
const response = await fetch('/static/js/emoji-a11y.en.json');
|
|
48
|
+
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.descriptions = await response.json();
|
|
54
|
+
this.logger.log(`[EmojiA11y] Loaded ${Object.keys(this.descriptions).length} emoji descriptions`);
|
|
55
|
+
} catch (e) {
|
|
56
|
+
console.warn('[EmojiA11y] Failed to load descriptions:', e);
|
|
57
|
+
this.descriptions = {};
|
|
58
|
+
this.enabled = false;
|
|
59
|
+
} finally {
|
|
60
|
+
this.loading = null;
|
|
61
|
+
}
|
|
62
|
+
})();
|
|
63
|
+
|
|
64
|
+
return this.loading;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get description for an emoji character.
|
|
69
|
+
*
|
|
70
|
+
* @param {string} emoji - Emoji character
|
|
71
|
+
* @returns {string|null} - Description or null if not found
|
|
72
|
+
*/
|
|
73
|
+
getDescription(emoji) {
|
|
74
|
+
if (!this.descriptions) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return this.descriptions[emoji] || null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Wrap emoji with accessible ARIA span.
|
|
83
|
+
*
|
|
84
|
+
* @param {string} emoji - Emoji character
|
|
85
|
+
* @returns {string} - HTML string with aria-label or plain emoji
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* wrapWithAria('') → '<span aria-label="mobile phone" role="img"></span>'
|
|
89
|
+
* wrapWithAria('A') → 'A' (not an emoji)
|
|
90
|
+
*/
|
|
91
|
+
wrapWithAria(emoji) {
|
|
92
|
+
if (!this.enabled) {
|
|
93
|
+
return emoji;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const desc = this.getDescription(emoji);
|
|
97
|
+
|
|
98
|
+
if (desc) {
|
|
99
|
+
// Escape HTML in description to prevent XSS
|
|
100
|
+
const safeDesc = this._escapeHtml(desc);
|
|
101
|
+
return `<span aria-label="${safeDesc}" role="img">${emoji}</span>`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return emoji;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Enhance text by wrapping all emojis with ARIA labels.
|
|
109
|
+
*
|
|
110
|
+
* @param {string} text - Plain or HTML text with emojis
|
|
111
|
+
* @returns {string} - Text with emojis wrapped in accessible spans
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* enhanceText('Mobile: ') → 'Mobile: <span aria-label="mobile phone" role="img"></span>'
|
|
115
|
+
*/
|
|
116
|
+
enhanceText(text) {
|
|
117
|
+
if (!this.enabled || !this.descriptions) {
|
|
118
|
+
return text;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Emoji Unicode ranges (same as Python version)
|
|
122
|
+
// Matches: emoji characters only (excludes ASCII)
|
|
123
|
+
const emojiRegex = /[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{1F000}-\u{1F0FF}\u{1F200}-\u{1F2FF}\u{1F600}-\u{1F64F}\u{1F680}-\u{1F6FF}\u{1F900}-\u{1F9FF}\u{2300}-\u{23FF}\u{2B00}-\u{2BFF}\u{FE00}-\u{FE0F}]/gu;
|
|
124
|
+
|
|
125
|
+
return text.replace(emojiRegex, (emoji) => {
|
|
126
|
+
return this.wrapWithAria(emoji);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Escape HTML entities to prevent XSS.
|
|
132
|
+
*
|
|
133
|
+
* @private
|
|
134
|
+
* @param {string} text - Text to escape
|
|
135
|
+
* @returns {string} - Escaped text
|
|
136
|
+
*/
|
|
137
|
+
_escapeHtml(text) {
|
|
138
|
+
// SSOT escape (also escapes " / ' — safe for the aria-label attribute)
|
|
139
|
+
return escapeHtml(text);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Check if emoji accessibility is enabled and loaded.
|
|
144
|
+
*
|
|
145
|
+
* @returns {boolean}
|
|
146
|
+
*/
|
|
147
|
+
isReady() {
|
|
148
|
+
return this.enabled && this.descriptions !== null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Get statistics about loaded descriptions.
|
|
153
|
+
*
|
|
154
|
+
* @returns {object} - Stats object
|
|
155
|
+
*/
|
|
156
|
+
getStats() {
|
|
157
|
+
return {
|
|
158
|
+
enabled: this.enabled,
|
|
159
|
+
loaded: this.descriptions !== null,
|
|
160
|
+
count: this.descriptions ? Object.keys(this.descriptions).length : 0
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Global singleton instance
|
|
166
|
+
const emojiAccessibility = new EmojiAccessibility();
|
|
167
|
+
|
|
168
|
+
// Auto-load on module import (non-blocking)
|
|
169
|
+
emojiAccessibility.load().catch(console.error);
|
|
170
|
+
|
|
171
|
+
// Export for use in Bifrost
|
|
172
|
+
export default emojiAccessibility;
|
|
173
|
+
export { EmojiAccessibility };
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Block Wrapper Utilities
|
|
4
|
+
*
|
|
5
|
+
*
|
|
6
|
+
* Helper functions for creating and managing zBlock wrappers with metadata.
|
|
7
|
+
* Supports both static and progressive rendering patterns.
|
|
8
|
+
*
|
|
9
|
+
* @module utils/block_utils
|
|
10
|
+
* @version 1.0.0
|
|
11
|
+
* @author Gal Nachshon
|
|
12
|
+
*
|
|
13
|
+
*
|
|
14
|
+
* Architecture:
|
|
15
|
+
* - Uses primitives for DOM creation (createDiv)
|
|
16
|
+
* - Handles _zClass and _zStyle metadata
|
|
17
|
+
* - Supports progressive rendering with data attributes
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// ─────────────────────────────────────────────────────────────────
|
|
22
|
+
// Imports
|
|
23
|
+
// ─────────────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
// Layer 2: Utilities
|
|
26
|
+
import { createDiv } from './dom_utils.js';
|
|
27
|
+
import { convertStyleToString } from './style_utils.js';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Create a block wrapper with metadata
|
|
31
|
+
* @param {Object} blockData - Block data object (may contain _zClass, _zStyle)
|
|
32
|
+
* @param {string} blockName - Block name for data attribute (default: 'zBlock')
|
|
33
|
+
* @param {boolean} isProgressive - Whether this is for progressive rendering (default: false)
|
|
34
|
+
* @returns {HTMLElement|null} Block wrapper div, or null if no metadata
|
|
35
|
+
*/
|
|
36
|
+
export function createBlockWrapper(blockData, blockName = 'zBlock', isProgressive = false) {
|
|
37
|
+
if (!blockData || typeof blockData !== 'object' || !blockData._zClass) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const blockLevelDiv = createDiv();
|
|
42
|
+
|
|
43
|
+
// Apply block-level classes
|
|
44
|
+
const classes = Array.isArray(blockData._zClass)
|
|
45
|
+
? blockData._zClass
|
|
46
|
+
: blockData._zClass.split(',').map(c => c.trim());
|
|
47
|
+
blockLevelDiv.className = classes.join(' ');
|
|
48
|
+
|
|
49
|
+
// Set data attribute
|
|
50
|
+
blockLevelDiv.setAttribute('data-zblock', isProgressive ? 'progressive' : blockName);
|
|
51
|
+
|
|
52
|
+
// Set id for named blocks (not progressive)
|
|
53
|
+
if (!isProgressive && blockName && blockName !== 'zBlock') {
|
|
54
|
+
blockLevelDiv.setAttribute('id', blockName);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Apply inline styles if present
|
|
58
|
+
if (blockData._zStyle) {
|
|
59
|
+
const cssString = convertStyleToString(blockData._zStyle);
|
|
60
|
+
if (cssString) {
|
|
61
|
+
blockLevelDiv.setAttribute('style', cssString);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return blockLevelDiv;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Apply block metadata to an existing wrapper
|
|
70
|
+
* @param {HTMLElement} wrapper - The wrapper element
|
|
71
|
+
* @param {Object} metadata - Metadata object (may contain _zClass, _zStyle)
|
|
72
|
+
*/
|
|
73
|
+
export function applyBlockMetadata(wrapper, metadata) {
|
|
74
|
+
if (!wrapper || !metadata) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (metadata._zClass) {
|
|
79
|
+
wrapper.className = metadata._zClass;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (metadata._zStyle) {
|
|
83
|
+
const cssString = convertStyleToString(metadata._zStyle);
|
|
84
|
+
if (cssString) {
|
|
85
|
+
wrapper.setAttribute('style', cssString);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Find existing progressive block wrapper in container
|
|
92
|
+
* @param {HTMLElement} container - Container to search in
|
|
93
|
+
* @returns {HTMLElement|null} Existing wrapper, or null
|
|
94
|
+
*/
|
|
95
|
+
export function findProgressiveBlockWrapper(container) {
|
|
96
|
+
if (!container) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
return container.querySelector('[data-zblock="progressive"]');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Check if block data has metadata (_zClass or _zStyle)
|
|
104
|
+
* @param {Object} blockData - Block data object
|
|
105
|
+
* @returns {boolean} True if has metadata
|
|
106
|
+
*/
|
|
107
|
+
export function hasBlockMetadata(blockData) {
|
|
108
|
+
return blockData &&
|
|
109
|
+
typeof blockData === 'object' &&
|
|
110
|
+
(blockData._zClass || blockData._zStyle);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
//
|
|
114
|
+
// Default Export (for convenience)
|
|
115
|
+
//
|
|
116
|
+
export default {
|
|
117
|
+
createBlockWrapper,
|
|
118
|
+
applyBlockMetadata,
|
|
119
|
+
findProgressiveBlockWrapper,
|
|
120
|
+
hasBlockMetadata
|
|
121
|
+
};
|
|
122
|
+
|