bitwrench 2.0.16 → 2.0.17
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/dist/bitwrench-bccl.cjs.js +6 -2
- package/dist/bitwrench-bccl.cjs.min.js +3 -3
- package/dist/bitwrench-bccl.esm.js +6 -2
- package/dist/bitwrench-bccl.esm.min.js +3 -3
- package/dist/bitwrench-bccl.umd.js +6 -2
- package/dist/bitwrench-bccl.umd.min.js +2 -2
- package/dist/bitwrench-code-edit.cjs.js +1 -1
- package/dist/bitwrench-code-edit.cjs.min.js +1 -1
- package/dist/bitwrench-code-edit.es5.js +1 -1
- package/dist/bitwrench-code-edit.es5.min.js +1 -1
- package/dist/bitwrench-code-edit.esm.js +1 -1
- package/dist/bitwrench-code-edit.esm.min.js +1 -1
- package/dist/bitwrench-code-edit.umd.js +1 -1
- package/dist/bitwrench-code-edit.umd.min.js +1 -1
- package/dist/bitwrench-lean.cjs.js +506 -154
- package/dist/bitwrench-lean.cjs.min.js +7 -7
- package/dist/bitwrench-lean.es5.js +517 -155
- package/dist/bitwrench-lean.es5.min.js +5 -5
- package/dist/bitwrench-lean.esm.js +505 -154
- package/dist/bitwrench-lean.esm.min.js +6 -6
- package/dist/bitwrench-lean.umd.js +506 -154
- package/dist/bitwrench-lean.umd.min.js +7 -7
- package/dist/bitwrench.cjs.js +511 -155
- package/dist/bitwrench.cjs.min.js +8 -8
- package/dist/bitwrench.es5.js +525 -156
- package/dist/bitwrench.es5.min.js +6 -6
- package/dist/bitwrench.esm.js +510 -155
- package/dist/bitwrench.esm.min.js +8 -8
- package/dist/bitwrench.umd.js +511 -155
- package/dist/bitwrench.umd.min.js +8 -8
- package/dist/builds.json +82 -82
- package/dist/bwserve.cjs.js +16 -2
- package/dist/bwserve.esm.js +16 -2
- package/dist/sri.json +34 -34
- package/package.json +4 -2
- package/readme.html +1 -1
- package/src/bitwrench-bccl.js +5 -1
- package/src/bitwrench.js +502 -151
- package/src/bwserve/index.js +12 -1
- package/src/bwserve/shell.js +3 -0
- package/src/cli/layout-default.js +47 -32
- package/src/version.js +3 -3
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
/*! bitwrench-lean v2.0.
|
|
1
|
+
/*! bitwrench-lean v2.0.17 | BSD-2-Clause | https://deftio.github.com/bitwrench/pages */
|
|
2
2
|
(function (global, factory) {
|
|
3
3
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
4
4
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
5
5
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bw = factory());
|
|
6
6
|
})(this, (function () { 'use strict';
|
|
7
7
|
|
|
8
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
8
9
|
function _arrayLikeToArray(r, a) {
|
|
9
10
|
(null == a || a > r.length) && (a = r.length);
|
|
10
11
|
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
@@ -189,14 +190,14 @@
|
|
|
189
190
|
*/
|
|
190
191
|
|
|
191
192
|
var VERSION_INFO = {
|
|
192
|
-
version: '2.0.
|
|
193
|
+
version: '2.0.17',
|
|
193
194
|
name: 'bitwrench',
|
|
194
195
|
description: 'A library for javascript UI functions.',
|
|
195
196
|
license: 'BSD-2-Clause',
|
|
196
197
|
homepage: 'https://deftio.github.com/bitwrench/pages',
|
|
197
198
|
repository: 'git+https://github.com/deftio/bitwrench.git',
|
|
198
199
|
author: 'manu a. chatterjee <deftio@deftio.com> (https://deftio.com/)',
|
|
199
|
-
buildDate: '2026-03-
|
|
200
|
+
buildDate: '2026-03-13T23:15:10.823Z'
|
|
200
201
|
};
|
|
201
202
|
|
|
202
203
|
/**
|
|
@@ -5125,7 +5126,7 @@
|
|
|
5125
5126
|
__monkey_patch_is_nodejs__: {
|
|
5126
5127
|
_value: 'ignore',
|
|
5127
5128
|
set: function set(x) {
|
|
5128
|
-
this._value =
|
|
5129
|
+
this._value = _is(x, 'boolean') ? x : 'ignore';
|
|
5129
5130
|
},
|
|
5130
5131
|
get: function get() {
|
|
5131
5132
|
return this._value;
|
|
@@ -5173,6 +5174,76 @@
|
|
|
5173
5174
|
configurable: true
|
|
5174
5175
|
});
|
|
5175
5176
|
|
|
5177
|
+
// ── Internal aliases ─────────────────────────────────────────────────────
|
|
5178
|
+
// Short names for frequently-used builtins and internal methods.
|
|
5179
|
+
// Same pattern as v1 (_to = bw.typeOf, etc.).
|
|
5180
|
+
//
|
|
5181
|
+
// Why: Terser can't shorten global property chains (console.warn,
|
|
5182
|
+
// Object.prototype.hasOwnProperty, Array.isArray, document.createElement)
|
|
5183
|
+
// because it can't prove they're side-effect-free. We can, so we alias
|
|
5184
|
+
// them here. Each alias saves bytes in the minified output, and the short
|
|
5185
|
+
// names also reduce visual noise in the hot paths (binding pipeline,
|
|
5186
|
+
// createDOM, etc.).
|
|
5187
|
+
//
|
|
5188
|
+
// Alias Target Sites
|
|
5189
|
+
// ───────── ────────────────────────────────────── ─────
|
|
5190
|
+
// _hop Object.prototype.hasOwnProperty 15
|
|
5191
|
+
// _isA Array.isArray 25
|
|
5192
|
+
// _keys Object.keys 7
|
|
5193
|
+
// _to bw.typeOf (type string) 26
|
|
5194
|
+
// _is type check boolean: _is(x,'string') ~50
|
|
5195
|
+
// _cw console.warn 8
|
|
5196
|
+
// _cl console.log 11
|
|
5197
|
+
// _ce console.error 4
|
|
5198
|
+
// _chp ComponentHandle.prototype 28 (defined after constructor)
|
|
5199
|
+
//
|
|
5200
|
+
// Note: document.createElement etc. are NOT aliased because they require
|
|
5201
|
+
// `this === document` and .bind() would add overhead on every call.
|
|
5202
|
+
// Console aliases use thin wrappers (not direct refs) so test monkey-
|
|
5203
|
+
// patching of console.warn/log/error continues to work.
|
|
5204
|
+
//
|
|
5205
|
+
// `typeof x` for UNDECLARED globals (window, document, process, require,
|
|
5206
|
+
// EventSource, navigator, Promise, __filename, import.meta) MUST stay as
|
|
5207
|
+
// raw `typeof` — calling _to(x) when x doesn't exist throws ReferenceError.
|
|
5208
|
+
//
|
|
5209
|
+
// ── v1 functional type helpers (kept for reference, not currently used) ──
|
|
5210
|
+
// _toa(x, type, trueVal, falseVal) — bw.typeAssign:
|
|
5211
|
+
// returns trueVal if _to(x)===type, else falseVal.
|
|
5212
|
+
// Replaces: (typeof x === 'string') ? A : B → _toa(x,'string',A,B)
|
|
5213
|
+
// _toc(x, type, trueVal, falseVal) — bw.typeConvert:
|
|
5214
|
+
// same as _toa but if trueVal/falseVal are functions, calls them with x.
|
|
5215
|
+
// Replaces: typeof x === 'string' ? fn(x) : default → _toc(x,'string',fn,default)
|
|
5216
|
+
// Uncomment if pattern frequency justifies them:
|
|
5217
|
+
// var _toa = function(x, t, y, n) { return _to(x) === t ? y : n; };
|
|
5218
|
+
// var _toc = function(x, t, y, n) { var r = _to(x)===t; return r ? (_to(y)==='function'?y(x):y) : (_to(n)==='function'?n(x):n); };
|
|
5219
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
5220
|
+
var _hop = Object.prototype.hasOwnProperty;
|
|
5221
|
+
var _isA = Array.isArray;
|
|
5222
|
+
var _keys = Object.keys;
|
|
5223
|
+
var _to = typeOf; // imported from bitwrench-utils.js
|
|
5224
|
+
var _is = function _is(x, t) {
|
|
5225
|
+
var r = _to(x);
|
|
5226
|
+
return r === t || r.toLowerCase() === t;
|
|
5227
|
+
};
|
|
5228
|
+
// Console aliases use thin wrappers (not direct references) so that test
|
|
5229
|
+
// code can monkey-patch console.warn/log/error and the patches take effect.
|
|
5230
|
+
var _cw = function _cw() {
|
|
5231
|
+
console.warn.apply(console, arguments);
|
|
5232
|
+
};
|
|
5233
|
+
var _cl = function _cl() {
|
|
5234
|
+
console.log.apply(console, arguments);
|
|
5235
|
+
};
|
|
5236
|
+
var _ce = function _ce() {
|
|
5237
|
+
console.error.apply(console, arguments);
|
|
5238
|
+
};
|
|
5239
|
+
|
|
5240
|
+
/**
|
|
5241
|
+
* Debug flag. When true, emits console.warn for silent binding failures
|
|
5242
|
+
* (missing paths, null refs, auto-created intermediate objects).
|
|
5243
|
+
* @type {boolean}
|
|
5244
|
+
*/
|
|
5245
|
+
bw.debug = false;
|
|
5246
|
+
|
|
5176
5247
|
/**
|
|
5177
5248
|
* Lazy-resolve Node.js `fs` module.
|
|
5178
5249
|
* Tries require('fs') first (available in CJS/UMD Node.js builds),
|
|
@@ -5322,7 +5393,7 @@
|
|
|
5322
5393
|
*/
|
|
5323
5394
|
bw._el = function (id) {
|
|
5324
5395
|
// Pass-through for DOM elements
|
|
5325
|
-
if (
|
|
5396
|
+
if (!_is(id, 'string')) return id || null;
|
|
5326
5397
|
if (!id) return null;
|
|
5327
5398
|
if (!bw._isBrowser) return null;
|
|
5328
5399
|
|
|
@@ -5417,7 +5488,7 @@
|
|
|
5417
5488
|
* // => '<b>Hello</b> & "world"'
|
|
5418
5489
|
*/
|
|
5419
5490
|
bw.escapeHTML = function (str) {
|
|
5420
|
-
if (
|
|
5491
|
+
if (!_is(str, 'string')) return '';
|
|
5421
5492
|
var escapeMap = {
|
|
5422
5493
|
'&': '&',
|
|
5423
5494
|
'<': '<',
|
|
@@ -5494,7 +5565,7 @@
|
|
|
5494
5565
|
}
|
|
5495
5566
|
|
|
5496
5567
|
// Handle arrays of TACOs
|
|
5497
|
-
if (
|
|
5568
|
+
if (_isA(taco)) {
|
|
5498
5569
|
return taco.map(function (t) {
|
|
5499
5570
|
return bw.html(t, options);
|
|
5500
5571
|
}).join('');
|
|
@@ -5517,17 +5588,17 @@
|
|
|
5517
5588
|
if (taco && taco._bwEach && options.state) {
|
|
5518
5589
|
var eachExpr = taco.expr.replace(/^\$\{|\}$/g, '');
|
|
5519
5590
|
var arr = bw._evaluatePath(options.state, eachExpr);
|
|
5520
|
-
if (!
|
|
5591
|
+
if (!_isA(arr)) return '';
|
|
5521
5592
|
return arr.map(function (item, idx) {
|
|
5522
5593
|
return bw.html(taco.factory(item, idx), options);
|
|
5523
5594
|
}).join('');
|
|
5524
5595
|
}
|
|
5525
5596
|
|
|
5526
5597
|
// Handle primitives and non-TACO objects
|
|
5527
|
-
if (
|
|
5598
|
+
if (!_is(taco, 'object') || !taco.t) {
|
|
5528
5599
|
var str = options.raw ? String(taco) : bw.escapeHTML(String(taco));
|
|
5529
5600
|
// Resolve template bindings if state provided
|
|
5530
|
-
if (options.state &&
|
|
5601
|
+
if (options.state && _is(str, 'string') && str.indexOf('${') >= 0) {
|
|
5531
5602
|
str = bw._resolveTemplate(str, options.state, !!options.compile);
|
|
5532
5603
|
}
|
|
5533
5604
|
return str;
|
|
@@ -5552,9 +5623,17 @@
|
|
|
5552
5623
|
// Skip null, undefined, false
|
|
5553
5624
|
if (value == null || value === false) continue;
|
|
5554
5625
|
|
|
5555
|
-
//
|
|
5556
|
-
if (key.startsWith('on'))
|
|
5557
|
-
|
|
5626
|
+
// Serialize event handlers via funcRegister
|
|
5627
|
+
if (key.startsWith('on')) {
|
|
5628
|
+
if (_is(value, 'function')) {
|
|
5629
|
+
var fnId = bw.funcRegister(value);
|
|
5630
|
+
attrStr += ' ' + key + '="' + bw.funcGetDispatchStr(fnId, 'event') + '"';
|
|
5631
|
+
} else if (_is(value, 'string')) {
|
|
5632
|
+
attrStr += ' ' + key + '="' + bw.escapeHTML(value) + '"';
|
|
5633
|
+
}
|
|
5634
|
+
continue;
|
|
5635
|
+
}
|
|
5636
|
+
if (key === 'style' && _is(value, 'object')) {
|
|
5558
5637
|
// Convert style object to string
|
|
5559
5638
|
var styleStr = Object.entries(value).filter(function (_ref) {
|
|
5560
5639
|
var _ref2 = _slicedToArray(_ref, 2),
|
|
@@ -5571,7 +5650,7 @@
|
|
|
5571
5650
|
}
|
|
5572
5651
|
} else if (key === 'class') {
|
|
5573
5652
|
// Handle class as array or string
|
|
5574
|
-
var classStr =
|
|
5653
|
+
var classStr = _isA(value) ? value.filter(Boolean).join(' ') : String(value);
|
|
5575
5654
|
if (classStr) {
|
|
5576
5655
|
attrStr += " class=\"".concat(bw.escapeHTML(classStr), "\"");
|
|
5577
5656
|
}
|
|
@@ -5607,12 +5686,184 @@
|
|
|
5607
5686
|
// Process content recursively
|
|
5608
5687
|
var contentStr = content != null ? bw.html(content, options) : '';
|
|
5609
5688
|
// Resolve template bindings in content if state provided
|
|
5610
|
-
if (options.state &&
|
|
5689
|
+
if (options.state && _is(contentStr, 'string') && contentStr.indexOf('${') >= 0) {
|
|
5611
5690
|
contentStr = bw._resolveTemplate(contentStr, options.state, !!options.compile);
|
|
5612
5691
|
}
|
|
5613
5692
|
return "<".concat(tag).concat(attrStr, ">").concat(contentStr, "</").concat(tag, ">");
|
|
5614
5693
|
};
|
|
5615
5694
|
|
|
5695
|
+
/**
|
|
5696
|
+
* Generate a complete, self-contained HTML document from TACO content.
|
|
5697
|
+
*
|
|
5698
|
+
* Produces a full `<!DOCTYPE html>` page with configurable runtime injection,
|
|
5699
|
+
* func registry emission (so serialized event handlers work), optional theme,
|
|
5700
|
+
* and extra head elements. Designed for static site generation, offline/airgapped
|
|
5701
|
+
* use, and the "static site that isn't static" workflow.
|
|
5702
|
+
*
|
|
5703
|
+
* @param {Object} [opts={}] - Page options
|
|
5704
|
+
* @param {Object|string|Array} [opts.body=''] - Body content: TACO, string, or array
|
|
5705
|
+
* @param {string} [opts.title='bitwrench'] - Page title
|
|
5706
|
+
* @param {Object} [opts.state] - State for ${expr} resolution in bw.html()
|
|
5707
|
+
* @param {string} [opts.runtime='shim'] - Runtime level: 'inline'|'cdn'|'shim'|'none'
|
|
5708
|
+
* @param {string} [opts.css=''] - Additional CSS for <style> block
|
|
5709
|
+
* @param {string|Object} [opts.theme=null] - Theme preset name or config object
|
|
5710
|
+
* @param {Array} [opts.head=[]] - Extra TACO elements rendered into <head>
|
|
5711
|
+
* @param {string} [opts.favicon=''] - Favicon URL
|
|
5712
|
+
* @param {string} [opts.lang='en'] - HTML lang attribute
|
|
5713
|
+
* @returns {string} Complete HTML document string
|
|
5714
|
+
* @category DOM Generation
|
|
5715
|
+
* @see bw.html
|
|
5716
|
+
* @example
|
|
5717
|
+
* bw.htmlPage({
|
|
5718
|
+
* title: 'My App',
|
|
5719
|
+
* body: { t: 'h1', c: 'Hello World' },
|
|
5720
|
+
* runtime: 'shim'
|
|
5721
|
+
* })
|
|
5722
|
+
*/
|
|
5723
|
+
bw.htmlPage = function (opts) {
|
|
5724
|
+
opts = opts || {};
|
|
5725
|
+
var title = opts.title || 'bitwrench';
|
|
5726
|
+
var body = opts.body || '';
|
|
5727
|
+
var state = opts.state || undefined;
|
|
5728
|
+
var runtime = opts.runtime || 'shim';
|
|
5729
|
+
var css = opts.css || '';
|
|
5730
|
+
var theme = opts.theme || null;
|
|
5731
|
+
var headExtra = opts.head || [];
|
|
5732
|
+
var favicon = opts.favicon || '';
|
|
5733
|
+
var lang = opts.lang || 'en';
|
|
5734
|
+
|
|
5735
|
+
// Snapshot funcRegistry counter before rendering
|
|
5736
|
+
var fnCounterBefore = bw._fnIDCounter;
|
|
5737
|
+
|
|
5738
|
+
// Render body content
|
|
5739
|
+
var bodyHTML = '';
|
|
5740
|
+
if (_is(body, 'string')) {
|
|
5741
|
+
bodyHTML = body;
|
|
5742
|
+
} else {
|
|
5743
|
+
var htmlOpts = {};
|
|
5744
|
+
if (state) htmlOpts.state = state;
|
|
5745
|
+
bodyHTML = bw.html(body, htmlOpts);
|
|
5746
|
+
}
|
|
5747
|
+
|
|
5748
|
+
// Collect functions registered during this render
|
|
5749
|
+
var fnCounterAfter = bw._fnIDCounter;
|
|
5750
|
+
var registryEntries = '';
|
|
5751
|
+
for (var i = fnCounterBefore; i < fnCounterAfter; i++) {
|
|
5752
|
+
var fnKey = 'bw_fn_' + i;
|
|
5753
|
+
if (bw._fnRegistry[fnKey]) {
|
|
5754
|
+
registryEntries += 'bw._fnRegistry[\'' + fnKey + '\']=' + bw._fnRegistry[fnKey].toString() + ';\n';
|
|
5755
|
+
}
|
|
5756
|
+
}
|
|
5757
|
+
|
|
5758
|
+
// Build runtime script for <head>
|
|
5759
|
+
var runtimeHead = '';
|
|
5760
|
+
if (runtime === 'inline') {
|
|
5761
|
+
// Read UMD bundle synchronously if in Node.js
|
|
5762
|
+
var umdSource = null;
|
|
5763
|
+
if (bw._isNode) {
|
|
5764
|
+
try {
|
|
5765
|
+
var fs = typeof require === 'function' ? require('fs') : null;
|
|
5766
|
+
var pathMod = typeof require === 'function' ? require('path') : null;
|
|
5767
|
+
if (fs && pathMod) {
|
|
5768
|
+
// Resolve dist/ relative to this source file
|
|
5769
|
+
var srcDir = '';
|
|
5770
|
+
try {
|
|
5771
|
+
srcDir = pathMod.dirname(typeof __filename !== 'undefined' ? __filename : '');
|
|
5772
|
+
} catch (e2) {/* ESM: __filename not available */}
|
|
5773
|
+
if (!srcDir && typeof ({ url: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bitwrench-lean.es5.js', document.baseURI).href)) }) !== 'undefined' && (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bitwrench-lean.es5.js', document.baseURI).href))) {
|
|
5774
|
+
var url = typeof require === 'function' ? require('url') : null;
|
|
5775
|
+
if (url && url.fileURLToPath) srcDir = pathMod.dirname(url.fileURLToPath((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bitwrench-lean.es5.js', document.baseURI).href))));
|
|
5776
|
+
}
|
|
5777
|
+
if (srcDir) {
|
|
5778
|
+
var distPath = pathMod.resolve(srcDir, '../dist/bitwrench.umd.min.js');
|
|
5779
|
+
umdSource = fs.readFileSync(distPath, 'utf8');
|
|
5780
|
+
}
|
|
5781
|
+
}
|
|
5782
|
+
} catch (e) {/* fall through */}
|
|
5783
|
+
}
|
|
5784
|
+
if (umdSource) {
|
|
5785
|
+
runtimeHead = '<script>' + umdSource + '</script>';
|
|
5786
|
+
} else {
|
|
5787
|
+
// Fallback to shim in browser or if dist not available
|
|
5788
|
+
runtimeHead = '<script>' + bw._FUNC_REGISTRY_SHIM + '</script>';
|
|
5789
|
+
}
|
|
5790
|
+
} else if (runtime === 'cdn') {
|
|
5791
|
+
runtimeHead = '<script src="https://cdn.jsdelivr.net/npm/bitwrench@2/dist/bitwrench.umd.min.js"></script>';
|
|
5792
|
+
} else if (runtime === 'shim') {
|
|
5793
|
+
runtimeHead = '<script>' + bw._FUNC_REGISTRY_SHIM + '</script>';
|
|
5794
|
+
}
|
|
5795
|
+
// runtime === 'none' → empty
|
|
5796
|
+
|
|
5797
|
+
// Theme CSS
|
|
5798
|
+
var themeCSS = '';
|
|
5799
|
+
if (theme) {
|
|
5800
|
+
var themeConfig = _is(theme, 'string') ? THEME_PRESETS[theme.toLowerCase()] || null : theme;
|
|
5801
|
+
if (themeConfig) {
|
|
5802
|
+
var themeResult = bw.generateTheme('', Object.assign({}, themeConfig, {
|
|
5803
|
+
inject: false
|
|
5804
|
+
}));
|
|
5805
|
+
themeCSS = themeResult.css;
|
|
5806
|
+
}
|
|
5807
|
+
}
|
|
5808
|
+
|
|
5809
|
+
// Extra <head> elements
|
|
5810
|
+
var headHTML = '';
|
|
5811
|
+
if (_isA(headExtra) && headExtra.length > 0) {
|
|
5812
|
+
headHTML = headExtra.map(function (el) {
|
|
5813
|
+
return bw.html(el);
|
|
5814
|
+
}).join('\n');
|
|
5815
|
+
}
|
|
5816
|
+
|
|
5817
|
+
// Favicon
|
|
5818
|
+
var faviconTag = '';
|
|
5819
|
+
if (favicon) {
|
|
5820
|
+
var safeFavicon = favicon.replace(/[&<>"']/g, function (c) {
|
|
5821
|
+
return {
|
|
5822
|
+
'&': '&',
|
|
5823
|
+
'<': '<',
|
|
5824
|
+
'>': '>',
|
|
5825
|
+
'"': '"',
|
|
5826
|
+
"'": '''
|
|
5827
|
+
}[c];
|
|
5828
|
+
});
|
|
5829
|
+
faviconTag = '<link rel="icon" href="' + safeFavicon + '">';
|
|
5830
|
+
}
|
|
5831
|
+
|
|
5832
|
+
// Escaped title
|
|
5833
|
+
var safeTitle = bw.escapeHTML(title);
|
|
5834
|
+
|
|
5835
|
+
// Combine all CSS
|
|
5836
|
+
var allCSS = (themeCSS ? themeCSS + '\n' : '') + css;
|
|
5837
|
+
|
|
5838
|
+
// Body-end script: registry entries + optional loadDefaultStyles
|
|
5839
|
+
var bodyEndScript = '';
|
|
5840
|
+
var bodyEndParts = [];
|
|
5841
|
+
if (registryEntries) {
|
|
5842
|
+
bodyEndParts.push(registryEntries);
|
|
5843
|
+
}
|
|
5844
|
+
if (runtime === 'inline' || runtime === 'cdn') {
|
|
5845
|
+
bodyEndParts.push('if(typeof bw!=="undefined"){bw.loadDefaultStyles();}');
|
|
5846
|
+
}
|
|
5847
|
+
if (bodyEndParts.length > 0) {
|
|
5848
|
+
bodyEndScript = '<script>\n' + bodyEndParts.join('\n') + '\n</script>';
|
|
5849
|
+
}
|
|
5850
|
+
|
|
5851
|
+
// Assemble document
|
|
5852
|
+
var parts = ['<!DOCTYPE html>', '<html lang="' + lang + '">', '<head>', '<meta charset="UTF-8">', '<meta name="viewport" content="width=device-width, initial-scale=1">'];
|
|
5853
|
+
parts.push('<title>' + safeTitle + '</title>');
|
|
5854
|
+
if (faviconTag) parts.push(faviconTag);
|
|
5855
|
+
if (runtimeHead) parts.push(runtimeHead);
|
|
5856
|
+
if (headHTML) parts.push(headHTML);
|
|
5857
|
+
if (allCSS) parts.push('<style>' + allCSS + '</style>');
|
|
5858
|
+
parts.push('</head>');
|
|
5859
|
+
parts.push('<body>');
|
|
5860
|
+
parts.push(bodyHTML);
|
|
5861
|
+
if (bodyEndScript) parts.push(bodyEndScript);
|
|
5862
|
+
parts.push('</body>');
|
|
5863
|
+
parts.push('</html>');
|
|
5864
|
+
return parts.join('\n');
|
|
5865
|
+
};
|
|
5866
|
+
|
|
5616
5867
|
/**
|
|
5617
5868
|
* Create a live DOM element from a TACO object (browser only).
|
|
5618
5869
|
*
|
|
@@ -5658,7 +5909,7 @@
|
|
|
5658
5909
|
}
|
|
5659
5910
|
|
|
5660
5911
|
// Handle text nodes
|
|
5661
|
-
if (
|
|
5912
|
+
if (!_is(taco, 'object') || !taco.t) {
|
|
5662
5913
|
return document.createTextNode(String(taco));
|
|
5663
5914
|
}
|
|
5664
5915
|
var tag = taco.t,
|
|
@@ -5677,16 +5928,16 @@
|
|
|
5677
5928
|
key = _Object$entries2$_i[0],
|
|
5678
5929
|
value = _Object$entries2$_i[1];
|
|
5679
5930
|
if (value == null || value === false) continue;
|
|
5680
|
-
if (key === 'style' &&
|
|
5931
|
+
if (key === 'style' && _is(value, 'object')) {
|
|
5681
5932
|
// Apply styles directly
|
|
5682
5933
|
Object.assign(el.style, value);
|
|
5683
5934
|
} else if (key === 'class') {
|
|
5684
5935
|
// Handle class as array or string
|
|
5685
|
-
var classStr =
|
|
5936
|
+
var classStr = _isA(value) ? value.filter(Boolean).join(' ') : String(value);
|
|
5686
5937
|
if (classStr) {
|
|
5687
5938
|
el.className = classStr;
|
|
5688
5939
|
}
|
|
5689
|
-
} else if (key.startsWith('on') &&
|
|
5940
|
+
} else if (key.startsWith('on') && _is(value, 'function')) {
|
|
5690
5941
|
// Event handlers
|
|
5691
5942
|
var eventName = key.slice(2).toLowerCase();
|
|
5692
5943
|
el.addEventListener(eventName, value);
|
|
@@ -5706,7 +5957,7 @@
|
|
|
5706
5957
|
// Children with data-bw_id or id attributes get local refs on the parent,
|
|
5707
5958
|
// so o.render functions can access them without any DOM lookup.
|
|
5708
5959
|
if (content != null) {
|
|
5709
|
-
if (
|
|
5960
|
+
if (_isA(content)) {
|
|
5710
5961
|
content.forEach(function (child) {
|
|
5711
5962
|
if (child != null) {
|
|
5712
5963
|
// Handle ComponentHandle in content arrays (Level 2 children)
|
|
@@ -5726,20 +5977,20 @@
|
|
|
5726
5977
|
if (childEl._bw_refs) {
|
|
5727
5978
|
if (!el._bw_refs) el._bw_refs = {};
|
|
5728
5979
|
for (var rk in childEl._bw_refs) {
|
|
5729
|
-
if (
|
|
5980
|
+
if (_hop.call(childEl._bw_refs, rk)) {
|
|
5730
5981
|
el._bw_refs[rk] = childEl._bw_refs[rk];
|
|
5731
5982
|
}
|
|
5732
5983
|
}
|
|
5733
5984
|
}
|
|
5734
5985
|
}
|
|
5735
5986
|
});
|
|
5736
|
-
} else if (
|
|
5987
|
+
} else if (_is(content, 'object') && content.__bw_raw) {
|
|
5737
5988
|
// Raw HTML content — inject via innerHTML
|
|
5738
5989
|
el.innerHTML = content.v;
|
|
5739
5990
|
} else if (content._bwComponent === true) {
|
|
5740
5991
|
// Single ComponentHandle as content
|
|
5741
5992
|
content.mount(el);
|
|
5742
|
-
} else if (
|
|
5993
|
+
} else if (_is(content, 'object') && content.t) {
|
|
5743
5994
|
var childEl = bw.createDOM(content, options);
|
|
5744
5995
|
el.appendChild(childEl);
|
|
5745
5996
|
var childBwId = content.a ? content.a['data-bw_id'] || content.a.id : null;
|
|
@@ -5750,7 +6001,7 @@
|
|
|
5750
6001
|
if (childEl._bw_refs) {
|
|
5751
6002
|
if (!el._bw_refs) el._bw_refs = {};
|
|
5752
6003
|
for (var rk in childEl._bw_refs) {
|
|
5753
|
-
if (
|
|
6004
|
+
if (_hop.call(childEl._bw_refs, rk)) {
|
|
5754
6005
|
el._bw_refs[rk] = childEl._bw_refs[rk];
|
|
5755
6006
|
}
|
|
5756
6007
|
}
|
|
@@ -5782,7 +6033,7 @@
|
|
|
5782
6033
|
if (opts.render) {
|
|
5783
6034
|
el._bw_render = opts.render;
|
|
5784
6035
|
if (opts.mounted) {
|
|
5785
|
-
|
|
6036
|
+
_cw('bw.createDOM: o.render and o.mounted are mutually exclusive. o.render wins.');
|
|
5786
6037
|
}
|
|
5787
6038
|
|
|
5788
6039
|
// Queue initial render (same timing as mounted)
|
|
@@ -5854,7 +6105,7 @@
|
|
|
5854
6105
|
// Get target element (use cache-backed lookup)
|
|
5855
6106
|
var targetEl = bw._el(target);
|
|
5856
6107
|
if (!targetEl) {
|
|
5857
|
-
|
|
6108
|
+
_ce('bw.DOM: Target element not found:', target);
|
|
5858
6109
|
return null;
|
|
5859
6110
|
}
|
|
5860
6111
|
|
|
@@ -5892,7 +6143,7 @@
|
|
|
5892
6143
|
targetEl.appendChild(taco.element);
|
|
5893
6144
|
}
|
|
5894
6145
|
// Handle arrays
|
|
5895
|
-
else if (
|
|
6146
|
+
else if (_isA(taco)) {
|
|
5896
6147
|
taco.forEach(function (t) {
|
|
5897
6148
|
if (t != null) {
|
|
5898
6149
|
if (t._bwComponent === true) {
|
|
@@ -5927,7 +6178,7 @@
|
|
|
5927
6178
|
bw.compileProps = function (handle) {
|
|
5928
6179
|
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
5929
6180
|
var compiledProps = {};
|
|
5930
|
-
|
|
6181
|
+
_keys(props).forEach(function (key) {
|
|
5931
6182
|
// Create getter/setter for each prop
|
|
5932
6183
|
Object.defineProperty(compiledProps, key, {
|
|
5933
6184
|
get: function get() {
|
|
@@ -6238,17 +6489,17 @@
|
|
|
6238
6489
|
if (attr) {
|
|
6239
6490
|
// Patch an attribute
|
|
6240
6491
|
el.setAttribute(attr, String(content));
|
|
6241
|
-
} else if (
|
|
6492
|
+
} else if (_isA(content)) {
|
|
6242
6493
|
// Patch with array of children (strings and/or TACOs)
|
|
6243
6494
|
el.innerHTML = '';
|
|
6244
6495
|
content.forEach(function (item) {
|
|
6245
|
-
if (
|
|
6496
|
+
if (_is(item, 'string') || _is(item, 'number')) {
|
|
6246
6497
|
el.appendChild(document.createTextNode(String(item)));
|
|
6247
6498
|
} else if (item && item.t) {
|
|
6248
6499
|
el.appendChild(bw.createDOM(item));
|
|
6249
6500
|
}
|
|
6250
6501
|
});
|
|
6251
|
-
} else if (
|
|
6502
|
+
} else if (_is(content, 'object') && content.t) {
|
|
6252
6503
|
// Patch with a TACO — replace children
|
|
6253
6504
|
el.innerHTML = '';
|
|
6254
6505
|
el.appendChild(bw.createDOM(content));
|
|
@@ -6279,7 +6530,7 @@
|
|
|
6279
6530
|
bw.patchAll = function (patches) {
|
|
6280
6531
|
var results = {};
|
|
6281
6532
|
for (var id in patches) {
|
|
6282
|
-
if (
|
|
6533
|
+
if (_hop.call(patches, id)) {
|
|
6283
6534
|
results[id] = bw.patch(id, patches[id]);
|
|
6284
6535
|
}
|
|
6285
6536
|
}
|
|
@@ -6376,7 +6627,7 @@
|
|
|
6376
6627
|
snapshot[i].handler(detail);
|
|
6377
6628
|
called++;
|
|
6378
6629
|
} catch (err) {
|
|
6379
|
-
|
|
6630
|
+
_cw('bw.pub: subscriber error on topic "' + topic + '":', err);
|
|
6380
6631
|
}
|
|
6381
6632
|
}
|
|
6382
6633
|
return called;
|
|
@@ -6477,8 +6728,8 @@
|
|
|
6477
6728
|
* @see bw.funcGetDispatchStr
|
|
6478
6729
|
*/
|
|
6479
6730
|
bw.funcRegister = function (fn, name) {
|
|
6480
|
-
if (
|
|
6481
|
-
var fnID =
|
|
6731
|
+
if (!_is(fn, 'function')) return '';
|
|
6732
|
+
var fnID = _is(name, 'string') && name.length > 0 ? name : 'bw_fn_' + bw._fnIDCounter++;
|
|
6482
6733
|
bw._fnRegistry[fnID] = fn;
|
|
6483
6734
|
return fnID;
|
|
6484
6735
|
};
|
|
@@ -6497,8 +6748,8 @@
|
|
|
6497
6748
|
bw.funcGetById = function (name, errFn) {
|
|
6498
6749
|
name = String(name);
|
|
6499
6750
|
if (name in bw._fnRegistry) return bw._fnRegistry[name];
|
|
6500
|
-
return
|
|
6501
|
-
|
|
6751
|
+
return _is(errFn, 'function') ? errFn : function () {
|
|
6752
|
+
_cw('bw.funcGetById: unregistered fn "' + name + '"');
|
|
6502
6753
|
};
|
|
6503
6754
|
};
|
|
6504
6755
|
|
|
@@ -6540,13 +6791,23 @@
|
|
|
6540
6791
|
bw.funcGetRegistry = function () {
|
|
6541
6792
|
var copy = {};
|
|
6542
6793
|
for (var k in bw._fnRegistry) {
|
|
6543
|
-
if (
|
|
6794
|
+
if (_hop.call(bw._fnRegistry, k)) {
|
|
6544
6795
|
copy[k] = bw._fnRegistry[k];
|
|
6545
6796
|
}
|
|
6546
6797
|
}
|
|
6547
6798
|
return copy;
|
|
6548
6799
|
};
|
|
6549
6800
|
|
|
6801
|
+
/**
|
|
6802
|
+
* Minimal runtime shim for funcRegister dispatch in static HTML.
|
|
6803
|
+
* When embedded in a `<script>` tag, provides just enough infrastructure
|
|
6804
|
+
* for `bw.funcGetById()` calls to resolve. The actual function bodies
|
|
6805
|
+
* are emitted separately as `bw._fnRegistry['bw_fn_X'] = ...;` assignments.
|
|
6806
|
+
* @type {string}
|
|
6807
|
+
* @category Function Registry
|
|
6808
|
+
*/
|
|
6809
|
+
bw._FUNC_REGISTRY_SHIM = '(function(){var bw=window.bw||(window.bw={});' + 'if(!bw._fnRegistry)bw._fnRegistry={};' + 'bw.funcGetById=function(n){return bw._fnRegistry[n]||function(){' + 'console.warn("bw: unregistered fn "+n)};};' + 'bw.funcRegister=function(fn,name){' + 'var id=name||("bw_fn_"+(bw._fnIDCounter=(bw._fnIDCounter||0)+1));' + 'bw._fnRegistry[id]=fn;return id;};' + 'window.bw=bw;})();';
|
|
6810
|
+
|
|
6550
6811
|
// ===================================================================================
|
|
6551
6812
|
// Template Binding Utilities
|
|
6552
6813
|
// ===================================================================================
|
|
@@ -6578,7 +6839,10 @@
|
|
|
6578
6839
|
var parts = path.split('.');
|
|
6579
6840
|
var val = state;
|
|
6580
6841
|
for (var i = 0; i < parts.length; i++) {
|
|
6581
|
-
if (val == null)
|
|
6842
|
+
if (val == null) {
|
|
6843
|
+
if (bw.debug) _cw('bw.debug: _evaluatePath — null at key "' + parts[i] + '" in path "' + path + '"');
|
|
6844
|
+
return '';
|
|
6845
|
+
}
|
|
6582
6846
|
val = val[parts[i]];
|
|
6583
6847
|
}
|
|
6584
6848
|
return val == null ? '' : val;
|
|
@@ -6598,7 +6862,7 @@
|
|
|
6598
6862
|
*/
|
|
6599
6863
|
bw._compiledExprs = {};
|
|
6600
6864
|
bw._resolveTemplate = function (str, state, compile) {
|
|
6601
|
-
if (
|
|
6865
|
+
if (!_is(str, 'string') || str.indexOf('${') < 0) return str;
|
|
6602
6866
|
var bindings = bw._parseBindings(str);
|
|
6603
6867
|
if (bindings.length === 0) return str;
|
|
6604
6868
|
var result = '';
|
|
@@ -6621,6 +6885,7 @@
|
|
|
6621
6885
|
try {
|
|
6622
6886
|
val = bw._compiledExprs[b.expr](state);
|
|
6623
6887
|
} catch (e) {
|
|
6888
|
+
if (bw.debug) _cw('bw.debug: _resolveTemplate — Tier 2 eval failed for "${' + b.expr + '}":', e.message);
|
|
6624
6889
|
val = '';
|
|
6625
6890
|
}
|
|
6626
6891
|
} else {
|
|
@@ -6728,7 +6993,7 @@
|
|
|
6728
6993
|
this._state = {};
|
|
6729
6994
|
if (o.state) {
|
|
6730
6995
|
for (var k in o.state) {
|
|
6731
|
-
if (
|
|
6996
|
+
if (_hop.call(o.state, k)) {
|
|
6732
6997
|
this._state[k] = o.state[k];
|
|
6733
6998
|
}
|
|
6734
6999
|
}
|
|
@@ -6737,7 +7002,7 @@
|
|
|
6737
7002
|
this._actions = {};
|
|
6738
7003
|
if (o.actions) {
|
|
6739
7004
|
for (var k2 in o.actions) {
|
|
6740
|
-
if (
|
|
7005
|
+
if (_hop.call(o.actions, k2)) {
|
|
6741
7006
|
this._actions[k2] = o.actions[k2];
|
|
6742
7007
|
}
|
|
6743
7008
|
}
|
|
@@ -6747,7 +7012,7 @@
|
|
|
6747
7012
|
if (o.methods) {
|
|
6748
7013
|
var self = this;
|
|
6749
7014
|
for (var k3 in o.methods) {
|
|
6750
|
-
if (
|
|
7015
|
+
if (_hop.call(o.methods, k3)) {
|
|
6751
7016
|
this._methods[k3] = o.methods[k3];
|
|
6752
7017
|
(function (methodName, methodFn) {
|
|
6753
7018
|
self[methodName] = function () {
|
|
@@ -6780,14 +7045,23 @@
|
|
|
6780
7045
|
this._compile = !!o.compile;
|
|
6781
7046
|
this._bw_refs = {};
|
|
6782
7047
|
this._refCounter = 0;
|
|
7048
|
+
// Child component ownership (Bug #5)
|
|
7049
|
+
this._children = [];
|
|
7050
|
+
this._parent = null;
|
|
7051
|
+
// Factory metadata for BCCL rebuild (Bug #6)
|
|
7052
|
+
this._factory = taco._bwFactory || null;
|
|
6783
7053
|
}
|
|
6784
7054
|
|
|
7055
|
+
// Short alias for ComponentHandle.prototype (see alias block at top of file).
|
|
7056
|
+
// 28 method definitions × 25 chars = ~700B raw savings in minified output.
|
|
7057
|
+
var _chp = ComponentHandle.prototype;
|
|
7058
|
+
|
|
6785
7059
|
// ── State Methods ──
|
|
6786
7060
|
|
|
6787
7061
|
/**
|
|
6788
7062
|
* Get a state value. Dot-path supported: `get('user.name')`
|
|
6789
7063
|
*/
|
|
6790
|
-
|
|
7064
|
+
_chp.get = function (key) {
|
|
6791
7065
|
return bw._evaluatePath(this._state, key);
|
|
6792
7066
|
};
|
|
6793
7067
|
|
|
@@ -6797,12 +7071,13 @@
|
|
|
6797
7071
|
* @param {*} value - New value
|
|
6798
7072
|
* @param {Object} [opts] - Options. `{sync: true}` for immediate flush.
|
|
6799
7073
|
*/
|
|
6800
|
-
|
|
7074
|
+
_chp.set = function (key, value, opts) {
|
|
6801
7075
|
// Dot-path set
|
|
6802
7076
|
var parts = key.split('.');
|
|
6803
7077
|
var obj = this._state;
|
|
6804
7078
|
for (var i = 0; i < parts.length - 1; i++) {
|
|
6805
|
-
if (
|
|
7079
|
+
if (!_is(obj[parts[i]], 'object')) {
|
|
7080
|
+
if (bw.debug) _cw('bw.debug: set() — auto-creating intermediate "' + parts[i] + '" in path "' + key + '"');
|
|
6806
7081
|
obj[parts[i]] = {};
|
|
6807
7082
|
}
|
|
6808
7083
|
obj = obj[parts[i]];
|
|
@@ -6822,10 +7097,10 @@
|
|
|
6822
7097
|
/**
|
|
6823
7098
|
* Get a shallow clone of the full state.
|
|
6824
7099
|
*/
|
|
6825
|
-
|
|
7100
|
+
_chp.getState = function () {
|
|
6826
7101
|
var clone = {};
|
|
6827
7102
|
for (var k in this._state) {
|
|
6828
|
-
if (
|
|
7103
|
+
if (_hop.call(this._state, k)) {
|
|
6829
7104
|
clone[k] = this._state[k];
|
|
6830
7105
|
}
|
|
6831
7106
|
}
|
|
@@ -6837,9 +7112,9 @@
|
|
|
6837
7112
|
* @param {Object} updates - Key-value pairs to merge
|
|
6838
7113
|
* @param {Object} [opts] - Options. `{sync: true}` for immediate flush.
|
|
6839
7114
|
*/
|
|
6840
|
-
|
|
7115
|
+
_chp.setState = function (updates, opts) {
|
|
6841
7116
|
for (var k in updates) {
|
|
6842
|
-
if (
|
|
7117
|
+
if (_hop.call(updates, k)) {
|
|
6843
7118
|
this._state[k] = updates[k];
|
|
6844
7119
|
this._dirtyKeys[k] = true;
|
|
6845
7120
|
}
|
|
@@ -6856,9 +7131,9 @@
|
|
|
6856
7131
|
/**
|
|
6857
7132
|
* Push a value onto an array in state. Clones the array.
|
|
6858
7133
|
*/
|
|
6859
|
-
|
|
7134
|
+
_chp.push = function (key, val) {
|
|
6860
7135
|
var arr = this.get(key);
|
|
6861
|
-
var newArr =
|
|
7136
|
+
var newArr = _isA(arr) ? arr.slice() : [];
|
|
6862
7137
|
newArr.push(val);
|
|
6863
7138
|
this.set(key, newArr);
|
|
6864
7139
|
};
|
|
@@ -6866,9 +7141,9 @@
|
|
|
6866
7141
|
/**
|
|
6867
7142
|
* Splice an array in state. Clones the array.
|
|
6868
7143
|
*/
|
|
6869
|
-
|
|
7144
|
+
_chp.splice = function (key, start, deleteCount) {
|
|
6870
7145
|
var arr = this.get(key);
|
|
6871
|
-
var newArr =
|
|
7146
|
+
var newArr = _isA(arr) ? arr.slice() : [];
|
|
6872
7147
|
var args = [start, deleteCount].concat(Array.prototype.slice.call(arguments, 3));
|
|
6873
7148
|
Array.prototype.splice.apply(newArr, args);
|
|
6874
7149
|
this.set(key, newArr);
|
|
@@ -6876,7 +7151,7 @@
|
|
|
6876
7151
|
|
|
6877
7152
|
// ── Scheduling ──
|
|
6878
7153
|
|
|
6879
|
-
|
|
7154
|
+
_chp._scheduleDirty = function () {
|
|
6880
7155
|
if (!this._scheduled) {
|
|
6881
7156
|
this._scheduled = true;
|
|
6882
7157
|
bw._dirtyComponents.push(this);
|
|
@@ -6891,16 +7166,16 @@
|
|
|
6891
7166
|
* Creates binding descriptors with refIds for targeted DOM updates.
|
|
6892
7167
|
* @private
|
|
6893
7168
|
*/
|
|
6894
|
-
|
|
7169
|
+
_chp._compileBindings = function () {
|
|
6895
7170
|
this._bindings = [];
|
|
6896
7171
|
this._refCounter = 0;
|
|
6897
|
-
var stateKeys =
|
|
7172
|
+
var stateKeys = _keys(this._state);
|
|
6898
7173
|
var self = this;
|
|
6899
7174
|
function walkTaco(taco, path) {
|
|
6900
|
-
if (
|
|
7175
|
+
if (!_is(taco, 'object') || !taco.t) return taco;
|
|
6901
7176
|
|
|
6902
7177
|
// Check content for bindings
|
|
6903
|
-
if (
|
|
7178
|
+
if (_is(taco.c, 'string') && taco.c.indexOf('${') >= 0) {
|
|
6904
7179
|
var refId = 'bw_ref_' + self._refCounter++;
|
|
6905
7180
|
var parsed = bw._parseBindings(taco.c);
|
|
6906
7181
|
var deps = [];
|
|
@@ -6922,10 +7197,10 @@
|
|
|
6922
7197
|
// Check attributes for bindings
|
|
6923
7198
|
if (taco.a) {
|
|
6924
7199
|
for (var attrName in taco.a) {
|
|
6925
|
-
if (!
|
|
7200
|
+
if (!_hop.call(taco.a, attrName)) continue;
|
|
6926
7201
|
if (attrName === 'data-bw_ref') continue;
|
|
6927
7202
|
var attrVal = taco.a[attrName];
|
|
6928
|
-
if (
|
|
7203
|
+
if (_is(attrVal, 'string') && attrVal.indexOf('${') >= 0) {
|
|
6929
7204
|
var refId2 = 'bw_ref_' + self._refCounter++;
|
|
6930
7205
|
var parsed2 = bw._parseBindings(attrVal);
|
|
6931
7206
|
var deps2 = [];
|
|
@@ -6951,9 +7226,34 @@
|
|
|
6951
7226
|
}
|
|
6952
7227
|
|
|
6953
7228
|
// Recurse into children
|
|
6954
|
-
if (
|
|
7229
|
+
if (_isA(taco.c)) {
|
|
6955
7230
|
for (var i = 0; i < taco.c.length; i++) {
|
|
6956
|
-
|
|
7231
|
+
// Wrap string children with ${expr} in a span so patches target the span, not the parent
|
|
7232
|
+
if (_is(taco.c[i], 'string') && taco.c[i].indexOf('${') >= 0) {
|
|
7233
|
+
var mixedRefId = 'bw_ref_' + self._refCounter++;
|
|
7234
|
+
var mixedParsed = bw._parseBindings(taco.c[i]);
|
|
7235
|
+
var mixedDeps = [];
|
|
7236
|
+
for (var mi = 0; mi < mixedParsed.length; mi++) {
|
|
7237
|
+
mixedDeps = mixedDeps.concat(bw._extractDeps(mixedParsed[mi].expr, stateKeys));
|
|
7238
|
+
}
|
|
7239
|
+
self._bindings.push({
|
|
7240
|
+
expr: taco.c[i],
|
|
7241
|
+
type: 'content',
|
|
7242
|
+
refId: mixedRefId,
|
|
7243
|
+
deps: mixedDeps,
|
|
7244
|
+
template: taco.c[i]
|
|
7245
|
+
});
|
|
7246
|
+
// Replace string with a span wrapper so textContent targets the span only
|
|
7247
|
+
taco.c[i] = {
|
|
7248
|
+
t: 'span',
|
|
7249
|
+
a: {
|
|
7250
|
+
'data-bw_ref': mixedRefId,
|
|
7251
|
+
style: 'display:contents'
|
|
7252
|
+
},
|
|
7253
|
+
c: taco.c[i]
|
|
7254
|
+
};
|
|
7255
|
+
}
|
|
7256
|
+
if (_is(taco.c[i], 'object') && taco.c[i].t) {
|
|
6957
7257
|
walkTaco(taco.c[i], path.concat(i));
|
|
6958
7258
|
}
|
|
6959
7259
|
// Handle bw.when/bw.each markers
|
|
@@ -6988,7 +7288,7 @@
|
|
|
6988
7288
|
taco.c[i]._refId = eachRefId;
|
|
6989
7289
|
}
|
|
6990
7290
|
}
|
|
6991
|
-
} else if (
|
|
7291
|
+
} else if (_is(taco.c, 'object') && taco.c.t) {
|
|
6992
7292
|
walkTaco(taco.c, path.concat(0));
|
|
6993
7293
|
}
|
|
6994
7294
|
return taco;
|
|
@@ -7002,7 +7302,7 @@
|
|
|
7002
7302
|
* Build ref map from the live DOM after createDOM.
|
|
7003
7303
|
* @private
|
|
7004
7304
|
*/
|
|
7005
|
-
|
|
7305
|
+
_chp._collectRefs = function () {
|
|
7006
7306
|
this._bw_refs = {};
|
|
7007
7307
|
if (!this.element) return;
|
|
7008
7308
|
var els = this.element.querySelectorAll('[data-bw_ref]');
|
|
@@ -7023,7 +7323,7 @@
|
|
|
7023
7323
|
* Creates DOM, compiles bindings, registers actions, and calls lifecycle hooks.
|
|
7024
7324
|
* @param {Element} parentEl - DOM element to mount into
|
|
7025
7325
|
*/
|
|
7026
|
-
|
|
7326
|
+
_chp.mount = function (parentEl) {
|
|
7027
7327
|
// willMount hook
|
|
7028
7328
|
if (this._hooks.willMount) this._hooks.willMount(this);
|
|
7029
7329
|
|
|
@@ -7045,7 +7345,7 @@
|
|
|
7045
7345
|
// Register named actions in function registry
|
|
7046
7346
|
var self = this;
|
|
7047
7347
|
for (var actionName in this._actions) {
|
|
7048
|
-
if (
|
|
7348
|
+
if (_hop.call(this._actions, actionName)) {
|
|
7049
7349
|
var registeredName = this._bwId + '_' + actionName;
|
|
7050
7350
|
(function (aName) {
|
|
7051
7351
|
bw.funcRegister(function (evt) {
|
|
@@ -7064,6 +7364,11 @@
|
|
|
7064
7364
|
this.element = bw.createDOM(tacoForDOM);
|
|
7065
7365
|
this.element._bwComponentHandle = this;
|
|
7066
7366
|
this.element.setAttribute('data-bw_comp_id', this._bwId);
|
|
7367
|
+
|
|
7368
|
+
// Restore o.render from original TACO (stripped by _tacoForDOM)
|
|
7369
|
+
if (this.taco.o && this.taco.o.render) {
|
|
7370
|
+
this.element._bw_render = this.taco.o.render;
|
|
7371
|
+
}
|
|
7067
7372
|
if (this._userTag) {
|
|
7068
7373
|
this.element.classList.add(this._userTag);
|
|
7069
7374
|
}
|
|
@@ -7078,6 +7383,16 @@
|
|
|
7078
7383
|
this._resolveAndApplyAll();
|
|
7079
7384
|
this.mounted = true;
|
|
7080
7385
|
|
|
7386
|
+
// Scan for child ComponentHandles and link parent/child (Bug #5)
|
|
7387
|
+
var childEls = this.element.querySelectorAll('[data-bw_comp_id]');
|
|
7388
|
+
for (var ci = 0; ci < childEls.length; ci++) {
|
|
7389
|
+
var ch = childEls[ci]._bwComponentHandle;
|
|
7390
|
+
if (ch && ch !== this && !ch._parent) {
|
|
7391
|
+
ch._parent = this;
|
|
7392
|
+
this._children.push(ch);
|
|
7393
|
+
}
|
|
7394
|
+
}
|
|
7395
|
+
|
|
7081
7396
|
// mounted hook (backward compat: fn.length === 2 wraps (el, state))
|
|
7082
7397
|
if (this._hooks.mounted) {
|
|
7083
7398
|
if (this._hooks.mounted.length === 2) {
|
|
@@ -7086,15 +7401,20 @@
|
|
|
7086
7401
|
this._hooks.mounted(this);
|
|
7087
7402
|
}
|
|
7088
7403
|
}
|
|
7404
|
+
|
|
7405
|
+
// Invoke o.render on initial mount (if present)
|
|
7406
|
+
if (this.element._bw_render) {
|
|
7407
|
+
this.element._bw_render(this.element, this._state);
|
|
7408
|
+
}
|
|
7089
7409
|
};
|
|
7090
7410
|
|
|
7091
7411
|
/**
|
|
7092
7412
|
* Prepare TACO for initial render: resolve when/each markers.
|
|
7093
7413
|
* @private
|
|
7094
7414
|
*/
|
|
7095
|
-
|
|
7096
|
-
if (!
|
|
7097
|
-
if (
|
|
7415
|
+
_chp._prepareTaco = function (taco) {
|
|
7416
|
+
if (!_is(taco, 'object')) return;
|
|
7417
|
+
if (_isA(taco.c)) {
|
|
7098
7418
|
for (var i = taco.c.length - 1; i >= 0; i--) {
|
|
7099
7419
|
var child = taco.c[i];
|
|
7100
7420
|
if (child && child._bwWhen) {
|
|
@@ -7135,7 +7455,7 @@
|
|
|
7135
7455
|
var eachExprStr = child.expr.replace(/^\$\{|\}$/g, '');
|
|
7136
7456
|
var arr = bw._evaluatePath(this._state, eachExprStr);
|
|
7137
7457
|
var items = [];
|
|
7138
|
-
if (
|
|
7458
|
+
if (_isA(arr)) {
|
|
7139
7459
|
for (var j = 0; j < arr.length; j++) {
|
|
7140
7460
|
items.push(child.factory(arr[j], j));
|
|
7141
7461
|
}
|
|
@@ -7149,11 +7469,11 @@
|
|
|
7149
7469
|
c: items
|
|
7150
7470
|
};
|
|
7151
7471
|
}
|
|
7152
|
-
if (
|
|
7472
|
+
if (_is(taco.c[i], 'object') && taco.c[i].t) {
|
|
7153
7473
|
this._prepareTaco(taco.c[i]);
|
|
7154
7474
|
}
|
|
7155
7475
|
}
|
|
7156
|
-
} else if (
|
|
7476
|
+
} else if (_is(taco.c, 'object') && taco.c.t) {
|
|
7157
7477
|
this._prepareTaco(taco.c);
|
|
7158
7478
|
}
|
|
7159
7479
|
};
|
|
@@ -7162,12 +7482,12 @@
|
|
|
7162
7482
|
* Wire action name strings (in onclick etc.) to dispatch function calls.
|
|
7163
7483
|
* @private
|
|
7164
7484
|
*/
|
|
7165
|
-
|
|
7166
|
-
if (!
|
|
7485
|
+
_chp._wireActions = function (taco) {
|
|
7486
|
+
if (!_is(taco, 'object') || !taco.t) return;
|
|
7167
7487
|
if (taco.a) {
|
|
7168
7488
|
for (var key in taco.a) {
|
|
7169
|
-
if (!
|
|
7170
|
-
if (key.startsWith('on') &&
|
|
7489
|
+
if (!_hop.call(taco.a, key)) continue;
|
|
7490
|
+
if (key.startsWith('on') && _is(taco.a[key], 'string')) {
|
|
7171
7491
|
var actionName = taco.a[key];
|
|
7172
7492
|
if (actionName in this._actions) {
|
|
7173
7493
|
var registeredName = this._bwId + '_' + actionName;
|
|
@@ -7181,11 +7501,11 @@
|
|
|
7181
7501
|
}
|
|
7182
7502
|
}
|
|
7183
7503
|
}
|
|
7184
|
-
if (
|
|
7504
|
+
if (_isA(taco.c)) {
|
|
7185
7505
|
for (var i = 0; i < taco.c.length; i++) {
|
|
7186
7506
|
this._wireActions(taco.c[i]);
|
|
7187
7507
|
}
|
|
7188
|
-
} else if (
|
|
7508
|
+
} else if (_is(taco.c, 'object') && taco.c.t) {
|
|
7189
7509
|
this._wireActions(taco.c);
|
|
7190
7510
|
}
|
|
7191
7511
|
};
|
|
@@ -7194,7 +7514,7 @@
|
|
|
7194
7514
|
* Deep-clone a TACO tree, preserving _bwWhen/_bwEach markers and their factories.
|
|
7195
7515
|
* @private
|
|
7196
7516
|
*/
|
|
7197
|
-
|
|
7517
|
+
_chp._deepCloneTaco = function (taco) {
|
|
7198
7518
|
if (taco == null) return taco;
|
|
7199
7519
|
// Preserve _bwWhen / _bwEach markers (contain functions)
|
|
7200
7520
|
if (taco._bwWhen) {
|
|
@@ -7213,22 +7533,22 @@
|
|
|
7213
7533
|
_refId: taco._refId
|
|
7214
7534
|
};
|
|
7215
7535
|
}
|
|
7216
|
-
if (
|
|
7536
|
+
if (!_is(taco, 'object') || !taco.t) return taco;
|
|
7217
7537
|
var result = {
|
|
7218
7538
|
t: taco.t
|
|
7219
7539
|
};
|
|
7220
7540
|
if (taco.a) {
|
|
7221
7541
|
result.a = {};
|
|
7222
7542
|
for (var k in taco.a) {
|
|
7223
|
-
if (
|
|
7543
|
+
if (_hop.call(taco.a, k)) result.a[k] = taco.a[k];
|
|
7224
7544
|
}
|
|
7225
7545
|
}
|
|
7226
7546
|
if (taco.c != null) {
|
|
7227
|
-
if (
|
|
7547
|
+
if (_isA(taco.c)) {
|
|
7228
7548
|
result.c = taco.c.map(function (child) {
|
|
7229
7549
|
return this._deepCloneTaco(child);
|
|
7230
7550
|
}.bind(this));
|
|
7231
|
-
} else if (
|
|
7551
|
+
} else if (_is(taco.c, 'object')) {
|
|
7232
7552
|
result.c = this._deepCloneTaco(taco.c);
|
|
7233
7553
|
} else {
|
|
7234
7554
|
result.c = taco.c;
|
|
@@ -7242,31 +7562,34 @@
|
|
|
7242
7562
|
* Create a copy of TACO suitable for createDOM (strips o to prevent double lifecycle).
|
|
7243
7563
|
* @private
|
|
7244
7564
|
*/
|
|
7245
|
-
|
|
7246
|
-
if (!
|
|
7565
|
+
_chp._tacoForDOM = function (taco) {
|
|
7566
|
+
if (!_is(taco, 'object') || !taco.t) return taco;
|
|
7247
7567
|
var result = {
|
|
7248
7568
|
t: taco.t
|
|
7249
7569
|
};
|
|
7250
7570
|
if (taco.a) result.a = taco.a;
|
|
7251
7571
|
if (taco.c != null) {
|
|
7252
|
-
if (
|
|
7572
|
+
if (_isA(taco.c)) {
|
|
7253
7573
|
result.c = taco.c.map(function (child) {
|
|
7254
7574
|
return this._tacoForDOM(child);
|
|
7255
7575
|
}.bind(this));
|
|
7256
|
-
} else if (
|
|
7576
|
+
} else if (_is(taco.c, 'object') && taco.c.t) {
|
|
7257
7577
|
result.c = this._tacoForDOM(taco.c);
|
|
7258
7578
|
} else {
|
|
7259
7579
|
result.c = taco.c;
|
|
7260
7580
|
}
|
|
7261
7581
|
}
|
|
7262
7582
|
// Intentionally strip o (no mounted/unmount/state/render on sub-elements)
|
|
7583
|
+
if (taco.o && (taco.o.mounted || taco.o.render || taco.o.unmount)) {
|
|
7584
|
+
_cw('bw: _tacoForDOM stripped o.mounted/render/unmount from child <' + taco.t + '>. Use onclick attribute or bw.component() for child interactivity.');
|
|
7585
|
+
}
|
|
7263
7586
|
return result;
|
|
7264
7587
|
};
|
|
7265
7588
|
|
|
7266
7589
|
/**
|
|
7267
7590
|
* Unmount: remove from DOM, deactivate, preserve state for re-mount.
|
|
7268
7591
|
*/
|
|
7269
|
-
|
|
7592
|
+
_chp.unmount = function () {
|
|
7270
7593
|
if (!this.mounted) return;
|
|
7271
7594
|
|
|
7272
7595
|
// unmount hook
|
|
@@ -7300,11 +7623,22 @@
|
|
|
7300
7623
|
/**
|
|
7301
7624
|
* Destroy: unmount + clear state + unregister actions.
|
|
7302
7625
|
*/
|
|
7303
|
-
|
|
7626
|
+
_chp.destroy = function () {
|
|
7304
7627
|
// willDestroy hook
|
|
7305
7628
|
if (this._hooks.willDestroy) {
|
|
7306
7629
|
this._hooks.willDestroy(this);
|
|
7307
7630
|
}
|
|
7631
|
+
|
|
7632
|
+
// Cascade destroy to children depth-first (Bug #5)
|
|
7633
|
+
for (var ci = this._children.length - 1; ci >= 0; ci--) {
|
|
7634
|
+
this._children[ci].destroy();
|
|
7635
|
+
}
|
|
7636
|
+
this._children = [];
|
|
7637
|
+
if (this._parent) {
|
|
7638
|
+
var idx = this._parent._children.indexOf(this);
|
|
7639
|
+
if (idx >= 0) this._parent._children.splice(idx, 1);
|
|
7640
|
+
this._parent = null;
|
|
7641
|
+
}
|
|
7308
7642
|
this.unmount();
|
|
7309
7643
|
|
|
7310
7644
|
// Unregister actions from function registry
|
|
@@ -7331,12 +7665,37 @@
|
|
|
7331
7665
|
* Flush dirty state: resolve changed bindings and apply to DOM.
|
|
7332
7666
|
* @private
|
|
7333
7667
|
*/
|
|
7334
|
-
|
|
7668
|
+
_chp._flush = function () {
|
|
7335
7669
|
this._scheduled = false;
|
|
7336
|
-
var changedKeys =
|
|
7670
|
+
var changedKeys = _keys(this._dirtyKeys);
|
|
7337
7671
|
this._dirtyKeys = {};
|
|
7338
7672
|
if (changedKeys.length === 0 || !this.mounted) return;
|
|
7339
7673
|
|
|
7674
|
+
// Factory rebuild: if a BCCL factory exists and changed keys overlap factory props,
|
|
7675
|
+
// rebuild the TACO from the factory with merged state (Bug #6)
|
|
7676
|
+
if (this._factory) {
|
|
7677
|
+
var rebuildNeeded = false;
|
|
7678
|
+
for (var fi = 0; fi < changedKeys.length; fi++) {
|
|
7679
|
+
if (_hop.call(this._factory.props, changedKeys[fi])) {
|
|
7680
|
+
rebuildNeeded = true;
|
|
7681
|
+
break;
|
|
7682
|
+
}
|
|
7683
|
+
}
|
|
7684
|
+
if (rebuildNeeded) {
|
|
7685
|
+
var merged = {};
|
|
7686
|
+
for (var mk in this._factory.props) if (_hop.call(this._factory.props, mk)) merged[mk] = this._factory.props[mk];
|
|
7687
|
+
for (var sk in this._state) if (_hop.call(this._state, sk)) merged[sk] = this._state[sk];
|
|
7688
|
+
this._factory.props = merged;
|
|
7689
|
+
var newTaco = bw.make(this._factory.type, merged);
|
|
7690
|
+
newTaco._bwFactory = this._factory;
|
|
7691
|
+
this.taco = newTaco;
|
|
7692
|
+
this._originalTaco = this._deepCloneTaco(newTaco);
|
|
7693
|
+
this._render();
|
|
7694
|
+
if (this._hooks.onUpdate) this._hooks.onUpdate(this, changedKeys);
|
|
7695
|
+
return;
|
|
7696
|
+
}
|
|
7697
|
+
}
|
|
7698
|
+
|
|
7340
7699
|
// willUpdate hook
|
|
7341
7700
|
if (this._hooks.willUpdate) {
|
|
7342
7701
|
this._hooks.willUpdate(this, changedKeys);
|
|
@@ -7374,7 +7733,7 @@
|
|
|
7374
7733
|
* Returns list of patches to apply.
|
|
7375
7734
|
* @private
|
|
7376
7735
|
*/
|
|
7377
|
-
|
|
7736
|
+
_chp._resolveBindings = function (changedKeys) {
|
|
7378
7737
|
var patches = [];
|
|
7379
7738
|
for (var i = 0; i < this._bindings.length; i++) {
|
|
7380
7739
|
var b = this._bindings[i];
|
|
@@ -7410,11 +7769,14 @@
|
|
|
7410
7769
|
* Apply patches to DOM.
|
|
7411
7770
|
* @private
|
|
7412
7771
|
*/
|
|
7413
|
-
|
|
7772
|
+
_chp._applyPatches = function (patches) {
|
|
7414
7773
|
for (var i = 0; i < patches.length; i++) {
|
|
7415
7774
|
var p = patches[i];
|
|
7416
7775
|
var el = this._bw_refs[p.refId];
|
|
7417
|
-
if (!el)
|
|
7776
|
+
if (!el) {
|
|
7777
|
+
if (bw.debug) _cw('bw.debug: _applyPatches — ref "' + p.refId + '" not found in DOM');
|
|
7778
|
+
continue;
|
|
7779
|
+
}
|
|
7418
7780
|
if (p.type === 'content') {
|
|
7419
7781
|
el.textContent = p.value;
|
|
7420
7782
|
} else if (p.type === 'attribute') {
|
|
@@ -7431,7 +7793,7 @@
|
|
|
7431
7793
|
* Resolve all bindings and apply (used for initial render).
|
|
7432
7794
|
* @private
|
|
7433
7795
|
*/
|
|
7434
|
-
|
|
7796
|
+
_chp._resolveAndApplyAll = function () {
|
|
7435
7797
|
var patches = [];
|
|
7436
7798
|
for (var i = 0; i < this._bindings.length; i++) {
|
|
7437
7799
|
var b = this._bindings[i];
|
|
@@ -7453,7 +7815,7 @@
|
|
|
7453
7815
|
* Full re-render for structural changes (when/each branch switches).
|
|
7454
7816
|
* @private
|
|
7455
7817
|
*/
|
|
7456
|
-
|
|
7818
|
+
_chp._render = function () {
|
|
7457
7819
|
if (!this.element || !this.element.parentNode) return;
|
|
7458
7820
|
var parent = this.element.parentNode;
|
|
7459
7821
|
var nextSibling = this.element.nextSibling;
|
|
@@ -7492,7 +7854,7 @@
|
|
|
7492
7854
|
* @param {string} event - Event name (e.g., 'click')
|
|
7493
7855
|
* @param {Function} handler - Event handler
|
|
7494
7856
|
*/
|
|
7495
|
-
|
|
7857
|
+
_chp.on = function (event, handler) {
|
|
7496
7858
|
if (this.element) {
|
|
7497
7859
|
this.element.addEventListener(event, handler);
|
|
7498
7860
|
}
|
|
@@ -7507,7 +7869,7 @@
|
|
|
7507
7869
|
* @param {string} event - Event name
|
|
7508
7870
|
* @param {Function} handler - Handler to remove
|
|
7509
7871
|
*/
|
|
7510
|
-
|
|
7872
|
+
_chp.off = function (event, handler) {
|
|
7511
7873
|
if (this.element) {
|
|
7512
7874
|
this.element.removeEventListener(event, handler);
|
|
7513
7875
|
}
|
|
@@ -7522,7 +7884,7 @@
|
|
|
7522
7884
|
* @param {Function} handler - Handler function
|
|
7523
7885
|
* @returns {Function} Unsubscribe function
|
|
7524
7886
|
*/
|
|
7525
|
-
|
|
7887
|
+
_chp.sub = function (topic, handler) {
|
|
7526
7888
|
var unsub = bw.sub(topic, handler);
|
|
7527
7889
|
this._subs.push(unsub);
|
|
7528
7890
|
return unsub;
|
|
@@ -7533,10 +7895,10 @@
|
|
|
7533
7895
|
* @param {string} name - Action name
|
|
7534
7896
|
* @param {...*} args - Arguments passed after comp
|
|
7535
7897
|
*/
|
|
7536
|
-
|
|
7898
|
+
_chp.action = function (name) {
|
|
7537
7899
|
var fn = this._actions[name];
|
|
7538
7900
|
if (!fn) {
|
|
7539
|
-
|
|
7901
|
+
_cw('ComponentHandle.action: unknown action "' + name + '"');
|
|
7540
7902
|
return;
|
|
7541
7903
|
}
|
|
7542
7904
|
var args = [this].concat(Array.prototype.slice.call(arguments, 1));
|
|
@@ -7548,7 +7910,7 @@
|
|
|
7548
7910
|
* @param {string} sel - CSS selector
|
|
7549
7911
|
* @returns {Element|null}
|
|
7550
7912
|
*/
|
|
7551
|
-
|
|
7913
|
+
_chp.select = function (sel) {
|
|
7552
7914
|
return this.element ? this.element.querySelector(sel) : null;
|
|
7553
7915
|
};
|
|
7554
7916
|
|
|
@@ -7557,7 +7919,7 @@
|
|
|
7557
7919
|
* @param {string} sel - CSS selector
|
|
7558
7920
|
* @returns {Element[]}
|
|
7559
7921
|
*/
|
|
7560
|
-
|
|
7922
|
+
_chp.selectAll = function (sel) {
|
|
7561
7923
|
if (!this.element) return [];
|
|
7562
7924
|
return Array.prototype.slice.call(this.element.querySelectorAll(sel));
|
|
7563
7925
|
};
|
|
@@ -7568,7 +7930,7 @@
|
|
|
7568
7930
|
* @param {string} tag - User-defined identifier (e.g. 'dashboard_prod_east')
|
|
7569
7931
|
* @returns {ComponentHandle} this (for chaining)
|
|
7570
7932
|
*/
|
|
7571
|
-
|
|
7933
|
+
_chp.userTag = function (tag) {
|
|
7572
7934
|
this._userTag = tag;
|
|
7573
7935
|
if (this.element) {
|
|
7574
7936
|
this.element.classList.add(tag);
|
|
@@ -7677,8 +8039,8 @@
|
|
|
7677
8039
|
}
|
|
7678
8040
|
if (!el || !el._bwComponentHandle) return false;
|
|
7679
8041
|
var comp = el._bwComponentHandle;
|
|
7680
|
-
if (
|
|
7681
|
-
|
|
8042
|
+
if (!_is(comp[action], 'function')) {
|
|
8043
|
+
_cw('bw.message: unknown action "' + action + '" on component ' + target);
|
|
7682
8044
|
return false;
|
|
7683
8045
|
}
|
|
7684
8046
|
comp[action](data);
|
|
@@ -7715,7 +8077,7 @@
|
|
|
7715
8077
|
},
|
|
7716
8078
|
focus: function focus(selector) {
|
|
7717
8079
|
var el = bw._el(selector);
|
|
7718
|
-
if (el &&
|
|
8080
|
+
if (el && _is(el.focus, 'function')) el.focus();
|
|
7719
8081
|
},
|
|
7720
8082
|
download: function download(filename, content, mimeType) {
|
|
7721
8083
|
if (typeof document === 'undefined') return;
|
|
@@ -7870,11 +8232,11 @@
|
|
|
7870
8232
|
} else if (type === 'remove') {
|
|
7871
8233
|
var toRemove = bw._el(target);
|
|
7872
8234
|
if (!toRemove) return false;
|
|
7873
|
-
if (
|
|
8235
|
+
if (_is(bw.cleanup, 'function')) bw.cleanup(toRemove);
|
|
7874
8236
|
toRemove.remove();
|
|
7875
8237
|
return true;
|
|
7876
8238
|
} else if (type === 'batch') {
|
|
7877
|
-
if (!
|
|
8239
|
+
if (!_isA(msg.ops)) return false;
|
|
7878
8240
|
var allOk = true;
|
|
7879
8241
|
msg.ops.forEach(function (op) {
|
|
7880
8242
|
if (!bw.clientApply(op)) allOk = false;
|
|
@@ -7888,24 +8250,24 @@
|
|
|
7888
8250
|
bw._clientFunctions[msg.name] = new Function('return ' + msg.body)();
|
|
7889
8251
|
return true;
|
|
7890
8252
|
} catch (e) {
|
|
7891
|
-
|
|
8253
|
+
_ce('[bw] register error:', msg.name, e);
|
|
7892
8254
|
return false;
|
|
7893
8255
|
}
|
|
7894
8256
|
} else if (type === 'call') {
|
|
7895
8257
|
if (!msg.name) return false;
|
|
7896
8258
|
var fn = bw._clientFunctions[msg.name] || bw._builtinClientFunctions[msg.name];
|
|
7897
|
-
if (
|
|
8259
|
+
if (!_is(fn, 'function')) return false;
|
|
7898
8260
|
try {
|
|
7899
|
-
var args =
|
|
8261
|
+
var args = _isA(msg.args) ? msg.args : [];
|
|
7900
8262
|
fn.apply(null, args);
|
|
7901
8263
|
return true;
|
|
7902
8264
|
} catch (e) {
|
|
7903
|
-
|
|
8265
|
+
_ce('[bw] call error:', msg.name, e);
|
|
7904
8266
|
return false;
|
|
7905
8267
|
}
|
|
7906
8268
|
} else if (type === 'exec') {
|
|
7907
8269
|
if (!bw._allowExec) {
|
|
7908
|
-
|
|
8270
|
+
_cw('[bw] exec rejected: allowExec is not enabled');
|
|
7909
8271
|
return false;
|
|
7910
8272
|
}
|
|
7911
8273
|
if (!msg.code) return false;
|
|
@@ -7913,7 +8275,7 @@
|
|
|
7913
8275
|
new Function(msg.code)();
|
|
7914
8276
|
return true;
|
|
7915
8277
|
} catch (e) {
|
|
7916
|
-
|
|
8278
|
+
_ce('[bw] exec error:', e);
|
|
7917
8279
|
return false;
|
|
7918
8280
|
}
|
|
7919
8281
|
}
|
|
@@ -7958,7 +8320,7 @@
|
|
|
7958
8320
|
}
|
|
7959
8321
|
function handleMessage(data) {
|
|
7960
8322
|
try {
|
|
7961
|
-
var msg =
|
|
8323
|
+
var msg = _is(data, 'string') ? bw.clientParse(data) : data;
|
|
7962
8324
|
if (onMessage) onMessage(msg);
|
|
7963
8325
|
if (handlers.message) handlers.message(msg);
|
|
7964
8326
|
bw.clientApply(msg);
|
|
@@ -7994,7 +8356,7 @@
|
|
|
7994
8356
|
fetch(url).then(function (r) {
|
|
7995
8357
|
return r.json();
|
|
7996
8358
|
}).then(function (msgs) {
|
|
7997
|
-
if (
|
|
8359
|
+
if (_isA(msgs)) {
|
|
7998
8360
|
msgs.forEach(handleMessage);
|
|
7999
8361
|
} else if (msgs && msgs.type) {
|
|
8000
8362
|
handleMessage(msgs);
|
|
@@ -8081,20 +8443,20 @@
|
|
|
8081
8443
|
el = target.element;
|
|
8082
8444
|
comp = target;
|
|
8083
8445
|
} else {
|
|
8084
|
-
if (
|
|
8446
|
+
if (_is(target, 'string')) {
|
|
8085
8447
|
el = bw.$(target)[0];
|
|
8086
8448
|
}
|
|
8087
8449
|
if (!el) {
|
|
8088
|
-
|
|
8450
|
+
_cw('bw.inspect: element not found');
|
|
8089
8451
|
return null;
|
|
8090
8452
|
}
|
|
8091
8453
|
comp = el._bwComponentHandle;
|
|
8092
8454
|
}
|
|
8093
8455
|
if (!comp) {
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8456
|
+
_cl('bw.inspect: no ComponentHandle on this element');
|
|
8457
|
+
_cl(' Tag:', el.tagName);
|
|
8458
|
+
_cl(' Classes:', el.className);
|
|
8459
|
+
_cl(' _bw_state:', el._bw_state || '(none)');
|
|
8098
8460
|
return null;
|
|
8099
8461
|
}
|
|
8100
8462
|
var deps = comp._bindings.reduce(function (s, b) {
|
|
@@ -8103,13 +8465,13 @@
|
|
|
8103
8465
|
return a.indexOf(v) === i;
|
|
8104
8466
|
});
|
|
8105
8467
|
console.group('Component: ' + comp._bwId);
|
|
8106
|
-
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8468
|
+
_cl('State:', comp._state);
|
|
8469
|
+
_cl('Bindings:', comp._bindings.length, '(deps:', deps, ')');
|
|
8470
|
+
_cl('Methods:', _keys(comp._methods));
|
|
8471
|
+
_cl('Actions:', _keys(comp._actions));
|
|
8472
|
+
_cl('User tag:', comp._userTag || '(none)');
|
|
8473
|
+
_cl('Mounted:', comp.mounted);
|
|
8474
|
+
_cl('Element:', comp.element);
|
|
8113
8475
|
console.groupEnd();
|
|
8114
8476
|
return comp;
|
|
8115
8477
|
};
|
|
@@ -8132,8 +8494,8 @@
|
|
|
8132
8494
|
// Pre-extract all binding expressions
|
|
8133
8495
|
var precompiled = [];
|
|
8134
8496
|
function walkExpressions(node) {
|
|
8135
|
-
if (!
|
|
8136
|
-
if (
|
|
8497
|
+
if (!_is(node, 'object')) return;
|
|
8498
|
+
if (_is(node.c, 'string') && node.c.indexOf('${') >= 0) {
|
|
8137
8499
|
var parsed = bw._parseBindings(node.c);
|
|
8138
8500
|
for (var i = 0; i < parsed.length; i++) {
|
|
8139
8501
|
try {
|
|
@@ -8153,9 +8515,9 @@
|
|
|
8153
8515
|
}
|
|
8154
8516
|
if (node.a) {
|
|
8155
8517
|
for (var key in node.a) {
|
|
8156
|
-
if (
|
|
8518
|
+
if (_hop.call(node.a, key)) {
|
|
8157
8519
|
var v = node.a[key];
|
|
8158
|
-
if (
|
|
8520
|
+
if (_is(v, 'string') && v.indexOf('${') >= 0) {
|
|
8159
8521
|
var parsed2 = bw._parseBindings(v);
|
|
8160
8522
|
for (var j = 0; j < parsed2.length; j++) {
|
|
8161
8523
|
try {
|
|
@@ -8176,9 +8538,9 @@
|
|
|
8176
8538
|
}
|
|
8177
8539
|
}
|
|
8178
8540
|
}
|
|
8179
|
-
if (
|
|
8541
|
+
if (_isA(node.c)) {
|
|
8180
8542
|
for (var k = 0; k < node.c.length; k++) walkExpressions(node.c[k]);
|
|
8181
|
-
} else if (
|
|
8543
|
+
} else if (_is(node.c, 'object') && node.c.t) {
|
|
8182
8544
|
walkExpressions(node.c);
|
|
8183
8545
|
}
|
|
8184
8546
|
}
|
|
@@ -8189,7 +8551,7 @@
|
|
|
8189
8551
|
handle._precompiledBindings = precompiled;
|
|
8190
8552
|
if (initialState) {
|
|
8191
8553
|
for (var k in initialState) {
|
|
8192
|
-
if (
|
|
8554
|
+
if (_hop.call(initialState, k)) {
|
|
8193
8555
|
handle._state[k] = initialState[k];
|
|
8194
8556
|
}
|
|
8195
8557
|
}
|
|
@@ -8223,21 +8585,21 @@
|
|
|
8223
8585
|
minify = _options$minify === void 0 ? false : _options$minify,
|
|
8224
8586
|
_options$pretty = options.pretty,
|
|
8225
8587
|
pretty = _options$pretty === void 0 ? !minify : _options$pretty;
|
|
8226
|
-
if (
|
|
8588
|
+
if (_is(rules, 'string')) return rules;
|
|
8227
8589
|
var css = '';
|
|
8228
8590
|
var indent = pretty ? ' ' : '';
|
|
8229
8591
|
var newline = pretty ? '\n' : '';
|
|
8230
8592
|
var space = pretty ? ' ' : '';
|
|
8231
|
-
if (
|
|
8593
|
+
if (_isA(rules)) {
|
|
8232
8594
|
css = rules.map(function (rule) {
|
|
8233
8595
|
return bw.css(rule, options);
|
|
8234
8596
|
}).join(newline);
|
|
8235
|
-
} else if (
|
|
8597
|
+
} else if (_is(rules, 'object')) {
|
|
8236
8598
|
Object.entries(rules).forEach(function (_ref5) {
|
|
8237
8599
|
var _ref6 = _slicedToArray(_ref5, 2),
|
|
8238
8600
|
selector = _ref6[0],
|
|
8239
8601
|
styles = _ref6[1];
|
|
8240
|
-
if (
|
|
8602
|
+
if (_is(styles, 'object')) {
|
|
8241
8603
|
// Handle @media, @keyframes, @supports — recurse into nested block
|
|
8242
8604
|
if (selector.charAt(0) === '@') {
|
|
8243
8605
|
var inner = bw.css(styles, options);
|
|
@@ -8291,7 +8653,7 @@
|
|
|
8291
8653
|
bw.injectCSS = function (css) {
|
|
8292
8654
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
8293
8655
|
if (!bw._isBrowser) {
|
|
8294
|
-
|
|
8656
|
+
_cw('bw.injectCSS requires a DOM environment');
|
|
8295
8657
|
return null;
|
|
8296
8658
|
}
|
|
8297
8659
|
var _options$id = options.id,
|
|
@@ -8309,7 +8671,7 @@
|
|
|
8309
8671
|
}
|
|
8310
8672
|
|
|
8311
8673
|
// Convert CSS if needed
|
|
8312
|
-
var cssStr =
|
|
8674
|
+
var cssStr = _is(css, 'string') ? css : bw.css(css, options);
|
|
8313
8675
|
|
|
8314
8676
|
// Set or append CSS
|
|
8315
8677
|
if (append && styleEl.textContent) {
|
|
@@ -8338,7 +8700,7 @@
|
|
|
8338
8700
|
var result = {};
|
|
8339
8701
|
for (var i = 0; i < arguments.length; i++) {
|
|
8340
8702
|
var arg = arguments[i];
|
|
8341
|
-
if (
|
|
8703
|
+
if (_is(arg, 'object')) Object.assign(result, arg);
|
|
8342
8704
|
}
|
|
8343
8705
|
return result;
|
|
8344
8706
|
};
|
|
@@ -8583,7 +8945,7 @@
|
|
|
8583
8945
|
xl: '1200px'
|
|
8584
8946
|
};
|
|
8585
8947
|
var parts = [];
|
|
8586
|
-
|
|
8948
|
+
_keys(breakpoints).forEach(function (key) {
|
|
8587
8949
|
var rules = {};
|
|
8588
8950
|
if (key === 'base') {
|
|
8589
8951
|
rules[selector] = breakpoints[key];
|
|
@@ -8655,18 +9017,18 @@
|
|
|
8655
9017
|
if (!selector) return [];
|
|
8656
9018
|
|
|
8657
9019
|
// Already an array
|
|
8658
|
-
if (
|
|
9020
|
+
if (_isA(selector)) return selector;
|
|
8659
9021
|
|
|
8660
9022
|
// Single element
|
|
8661
9023
|
if (selector.nodeType) return [selector];
|
|
8662
9024
|
|
|
8663
9025
|
// NodeList or HTMLCollection
|
|
8664
|
-
if (selector.length !== undefined &&
|
|
9026
|
+
if (selector.length !== undefined && !_is(selector, 'string')) {
|
|
8665
9027
|
return Array.from(selector);
|
|
8666
9028
|
}
|
|
8667
9029
|
|
|
8668
9030
|
// CSS selector string
|
|
8669
|
-
if (
|
|
9031
|
+
if (_is(selector, 'string')) {
|
|
8670
9032
|
return Array.from(document.querySelectorAll(selector));
|
|
8671
9033
|
}
|
|
8672
9034
|
return [];
|
|
@@ -9184,7 +9546,7 @@
|
|
|
9184
9546
|
cls = cls.trim();
|
|
9185
9547
|
|
|
9186
9548
|
// Auto-detect columns if not provided
|
|
9187
|
-
var cols = columns || (data.length > 0 ?
|
|
9549
|
+
var cols = columns || (data.length > 0 ? _keys(data[0]).map(function (key) {
|
|
9188
9550
|
return {
|
|
9189
9551
|
key: key,
|
|
9190
9552
|
label: key
|
|
@@ -9203,7 +9565,7 @@
|
|
|
9203
9565
|
var bVal = b[currentSortColumn];
|
|
9204
9566
|
|
|
9205
9567
|
// Handle different types
|
|
9206
|
-
if (
|
|
9568
|
+
if (_is(aVal, 'number') && _is(bVal, 'number')) {
|
|
9207
9569
|
return currentSortDirection === 'asc' ? aVal - bVal : bVal - aVal;
|
|
9208
9570
|
}
|
|
9209
9571
|
|
|
@@ -9327,7 +9689,7 @@
|
|
|
9327
9689
|
headerRow = _config$headerRow === void 0 ? true : _config$headerRow,
|
|
9328
9690
|
columns = config.columns,
|
|
9329
9691
|
rest = _objectWithoutProperties(config, _excluded);
|
|
9330
|
-
if (!
|
|
9692
|
+
if (!_isA(data) || data.length === 0) {
|
|
9331
9693
|
return bw.makeTable(_objectSpread2({
|
|
9332
9694
|
data: [],
|
|
9333
9695
|
columns: columns || []
|
|
@@ -9424,7 +9786,7 @@
|
|
|
9424
9786
|
showLabels = _config$showLabels === void 0 ? true : _config$showLabels,
|
|
9425
9787
|
_config$className2 = config.className,
|
|
9426
9788
|
className = _config$className2 === void 0 ? '' : _config$className2;
|
|
9427
|
-
if (!
|
|
9789
|
+
if (!_isA(data) || data.length === 0) {
|
|
9428
9790
|
return {
|
|
9429
9791
|
t: 'div',
|
|
9430
9792
|
a: {
|
|
@@ -9607,7 +9969,7 @@
|
|
|
9607
9969
|
bw.render = function (element, position, taco) {
|
|
9608
9970
|
var _taco$o4, _taco$o5, _taco$o6;
|
|
9609
9971
|
// Get target element
|
|
9610
|
-
var targetEl =
|
|
9972
|
+
var targetEl = _is(element, 'string') ? document.querySelector(element) : element;
|
|
9611
9973
|
if (!targetEl) {
|
|
9612
9974
|
return {
|
|
9613
9975
|
object_type: 'error',
|
|
@@ -9745,7 +10107,7 @@
|
|
|
9745
10107
|
setContent: function setContent(content) {
|
|
9746
10108
|
this._taco.c = content;
|
|
9747
10109
|
if (this.element) {
|
|
9748
|
-
if (
|
|
10110
|
+
if (_is(content, 'string')) {
|
|
9749
10111
|
this.element.textContent = content;
|
|
9750
10112
|
} else {
|
|
9751
10113
|
// Re-render for complex content
|