Skip to content

Commit 2684aa5

Browse files
committed
Add FeatureMap template helpers for static cluster config
- Add if_cluster_has_feature_bitmap, if_feature_bit_enabled, and cluster_feature_items helpers for Feature bitmap detection and per-bit checks in generated server cluster config templates. - Fix Electron 41 navigation and console-message handling, use navigationHistory for back/forward when available and support the new console-message event shape; allow Electron 41.x.x in env checks. - Adding unit tests - JIRA: ZAPP-1716
1 parent c7d8222 commit 2684aa5

8 files changed

Lines changed: 553 additions & 11 deletions

File tree

docs/api.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9196,6 +9196,10 @@ This module contains the API for templating. For more detailed instructions, rea
91969196
* [~featureBits(options)](#module_Templating API_ Attribute helpers..featureBits) ⇒
91979197
* [~attributeDefault()](#module_Templating API_ Attribute helpers..attributeDefault) ⇒
91989198
* [~as_underlying_atomic_identifier_for_attribute_id(attributeId)](#module_Templating API_ Attribute helpers..as_underlying_atomic_identifier_for_attribute_id)
9199+
* [~selectFeatureBitmapForCluster(db, packageIds, clusterId)](#module_Templating API_ Attribute helpers..selectFeatureBitmapForCluster) ⇒ <code>Promise.&lt;(object\|null)&gt;</code>
9200+
* [~if_cluster_has_feature_bitmap(options)](#module_Templating API_ Attribute helpers..if_cluster_has_feature_bitmap) ⇒ <code>Promise.&lt;string&gt;</code>
9201+
* [~if_feature_bit_enabled(options)](#module_Templating API_ Attribute helpers..if_feature_bit_enabled) ⇒ <code>string</code>
9202+
* [~cluster_feature_items(options)](#module_Templating API_ Attribute helpers..cluster_feature_items) ⇒ <code>Promise.&lt;string&gt;</code>
91999203

92009204
<a name="module_Templating API_ Attribute helpers..count_mandatory_matter_attributes"></a>
92019205

@@ -9236,6 +9240,139 @@ atomic table.
92369240
| --- | --- |
92379241
| attributeId | <code>\*</code> |
92389242

9243+
<a name="module_Templating API_ Attribute helpers..selectFeatureBitmapForCluster"></a>
9244+
9245+
### Templating API: Attribute helpers~selectFeatureBitmapForCluster(db, packageIds, clusterId) ⇒ <code>Promise.&lt;(object\|null)&gt;</code>
9246+
Returns the cluster-scoped 'Feature' bitmap, or null when the cluster does not
9247+
define one. Uses selectBitmapByNameAndClusterId for a targeted lookup, then
9248+
confirms the bitmap is associated with clusterId (the DB helper may return a
9249+
package-wide singleton when only one bitmap with that name exists).
9250+
9251+
**Kind**: inner method of [<code>Templating API: Attribute helpers</code>](#module_Templating API_ Attribute helpers)
9252+
9253+
| Param | Type |
9254+
| --- | --- |
9255+
| db | <code>\*</code> |
9256+
| packageIds | <code>Array.&lt;number&gt;</code> |
9257+
| clusterId | <code>number</code> |
9258+
9259+
<a name="module_Templating API_ Attribute helpers..if_cluster_has_feature_bitmap"></a>
9260+
9261+
### Templating API: Attribute helpers~if\_cluster\_has\_feature\_bitmap(options) ⇒ <code>Promise.&lt;string&gt;</code>
9262+
Block helper that renders its body when the cluster in the current context
9263+
defines a bitmap named 'Feature', and its inverse ({{else}}) when it does
9264+
not. Intended for choosing between `using FeatureBitmapType = Feature;` and
9265+
`using FeatureBitmapType = Clusters::StaticApplicationConfig::NoFeatureFlagsDefined;`
9266+
in static-cluster-config headers.
9267+
9268+
Must be used inside a context that exposes a cluster `id` field, such as
9269+
`zcl_clusters`, `selectedServerCluster`, or any block helper whose context
9270+
object carries the ZCL cluster database ID as `id`.
9271+
9272+
**Kind**: inner method of [<code>Templating API: Attribute helpers</code>](#module_Templating API_ Attribute helpers)
9273+
**Returns**: <code>Promise.&lt;string&gt;</code> - Rendered `fn` block when the cluster has a
9274+
bitmap named 'Feature'; rendered `inverse` block otherwise.
9275+
9276+
| Param | Type | Description |
9277+
| --- | --- | --- |
9278+
| options | <code>\*</code> | Handlebars options object (fn / inverse blocks). |
9279+
9280+
**Example**
9281+
```js
9282+
// Inside a selectedServerCluster or zcl_clusters block:
9283+
{{#if_cluster_has_feature_bitmap}}
9284+
using FeatureBitmapType = Feature;
9285+
{{else}}
9286+
using FeatureBitmapType = Clusters::StaticApplicationConfig::NoFeatureFlagsDefined;
9287+
{{/if_cluster_has_feature_bitmap}}
9288+
```
9289+
<a name="module_Templating API_ Attribute helpers..if_feature_bit_enabled"></a>
9290+
9291+
### Templating API: Attribute helpers~if\_feature\_bit\_enabled(options) ⇒ <code>string</code>
9292+
Block helper that renders its body when the bitwise AND of `featureMapValue`
9293+
and `mask` is non-zero (i.e. the specific feature bit is set), and its
9294+
inverse ({{else}}) when the bit is clear.
9295+
9296+
Both arguments are parsed as integers so decimal strings (e.g. `"3"`) and
9297+
hex strings (e.g. `"0x3"`) are accepted.
9298+
9299+
Combine with `cluster_feature_items` when you want to iterate over feature
9300+
fields and selectively render only those that are enabled:
9301+
{{#cluster_feature_items clusterCode}}
9302+
{{#if_feature_bit_enabled featureMapValue mask}}...{{/if_feature_bit_enabled}}
9303+
{{/cluster_feature_items}}
9304+
9305+
**Kind**: inner method of [<code>Templating API: Attribute helpers</code>](#module_Templating API_ Attribute helpers)
9306+
**Returns**: <code>string</code> - Rendered `fn` block when `(featureMapValue & mask) !== 0`;
9307+
rendered `inverse` block otherwise.
9308+
**Given**: <code>string\|number</code> featureMapValue - The raw FeatureMap attribute default
9309+
value for the current endpoint cluster (e.g. `"3"`).
9310+
**Given**: <code>string\|number</code> mask - The bitmask of the feature field being tested
9311+
(e.g. `1`).
9312+
9313+
| Param | Type | Description |
9314+
| --- | --- | --- |
9315+
| options | <code>\*</code> | Handlebars options object (fn / inverse blocks). |
9316+
9317+
**Example**
9318+
```js
9319+
// LevelControl, featureMap default = 3 (kOnOff | kLighting):
9320+
{{#if_feature_bit_enabled "3" "1"}}enabled{{else}}disabled{{/if_feature_bit_enabled}}
9321+
// → "enabled"
9322+
{{#if_feature_bit_enabled "3" "4"}}enabled{{else}}disabled{{/if_feature_bit_enabled}}
9323+
// → "disabled" (kFrequency bit 0x4 is not set)
9324+
```
9325+
<a name="module_Templating API_ Attribute helpers..cluster_feature_items"></a>
9326+
9327+
### Templating API: Attribute helpers~cluster\_feature\_items(options) ⇒ <code>Promise.&lt;string&gt;</code>
9328+
Block helper that iterates over all fields of the Feature bitmap for a
9329+
cluster identified by its ZCL cluster code, regardless of which bits are
9330+
currently enabled. Use `if_feature_bit_enabled` inside the body to act on
9331+
only those fields whose bit is set in a given FeatureMap value.
9332+
9333+
This is the preferred way to access Feature bitmap fields inside
9334+
`user_cluster_attributes` because `zcl_bitmaps` requires a cluster database
9335+
`id` in context that is not available there. This helper performs the cluster
9336+
lookup by ZCL code (not name) for robustness.
9337+
9338+
Each iteration context exposes:
9339+
- `name` {string} field name as stored in the ZCL database (e.g. `"kOnOff"`)
9340+
- `label` {string} same as `name`
9341+
- `mask` {number} the field's bitmask (e.g. `1`)
9342+
9343+
If the cluster has no bitmap named 'Feature' the body is never rendered.
9344+
9345+
**Kind**: inner method of [<code>Templating API: Attribute helpers</code>](#module_Templating API_ Attribute helpers)
9346+
**Returns**: <code>Promise.&lt;string&gt;</code> - Concatenated rendered blocks for each feature field.
9347+
**Given**: <code>string\|number</code> clusterCode - The ZCL cluster code (e.g. `8` for
9348+
LevelControl). Inside `user_cluster_attributes` pass `../code` to
9349+
reference the enclosing `user_clusters` cluster code.
9350+
9351+
| Param | Type | Description |
9352+
| --- | --- | --- |
9353+
| options | <code>\*</code> | Handlebars options object. |
9354+
9355+
**Example**
9356+
```js
9357+
// List only enabled feature bits for LevelControl (featureMap default = 3):
9358+
{{#if (is_str_equal name "FeatureMap")}}
9359+
{{#cluster_feature_items ../code}}
9360+
{{#if_feature_bit_enabled ../defaultValue mask}}
9361+
FeatureBitmapType::k{{asUpperCamelCase label preserveAcronyms=true}}, // feature bit {{as_hex mask}}
9362+
{{/if_feature_bit_enabled}}
9363+
{{/cluster_feature_items}}
9364+
{{/if}}
9365+
// Emits: FeatureBitmapType::kOnOff, // feature bit 0x1
9366+
// FeatureBitmapType::kLighting, // feature bit 0x2
9367+
// Skips kFrequency (mask 0x4 not set in value 3)
9368+
```
9369+
**Example**
9370+
```js
9371+
// List ALL defined feature bits regardless of enabled state:
9372+
{{#cluster_feature_items clusterCode}}
9373+
{{label}}: {{as_hex mask}}
9374+
{{/cluster_feature_items}}
9375+
```
92399376
<a name="module_Templating API_ C formatting helpers"></a>
92409377

92419378
## Templating API: C formatting helpers

docs/helpers.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ This module contains the API for templating. For more detailed instructions, rea
221221
* [~featureBits(options)](#module_Templating API_ Attribute helpers..featureBits) ⇒
222222
* [~attributeDefault()](#module_Templating API_ Attribute helpers..attributeDefault) ⇒
223223
* [~as_underlying_atomic_identifier_for_attribute_id(attributeId)](#module_Templating API_ Attribute helpers..as_underlying_atomic_identifier_for_attribute_id)
224+
* [~selectFeatureBitmapForCluster(db, packageIds, clusterId)](#module_Templating API_ Attribute helpers..selectFeatureBitmapForCluster) ⇒ <code>Promise.&lt;(object\|null)&gt;</code>
225+
* [~if_cluster_has_feature_bitmap(options)](#module_Templating API_ Attribute helpers..if_cluster_has_feature_bitmap) ⇒ <code>Promise.&lt;string&gt;</code>
226+
* [~if_feature_bit_enabled(options)](#module_Templating API_ Attribute helpers..if_feature_bit_enabled) ⇒ <code>string</code>
227+
* [~cluster_feature_items(options)](#module_Templating API_ Attribute helpers..cluster_feature_items) ⇒ <code>Promise.&lt;string&gt;</code>
224228

225229
<a name="module_Templating API_ Attribute helpers..count_mandatory_matter_attributes"></a>
226230

@@ -261,6 +265,139 @@ atomic table.
261265
| --- | --- |
262266
| attributeId | <code>\*</code> |
263267

268+
<a name="module_Templating API_ Attribute helpers..selectFeatureBitmapForCluster"></a>
269+
270+
### Templating API: Attribute helpers~selectFeatureBitmapForCluster(db, packageIds, clusterId) ⇒ <code>Promise.&lt;(object\|null)&gt;</code>
271+
Returns the cluster-scoped 'Feature' bitmap, or null when the cluster does not
272+
define one. Uses selectBitmapByNameAndClusterId for a targeted lookup, then
273+
confirms the bitmap is associated with clusterId (the DB helper may return a
274+
package-wide singleton when only one bitmap with that name exists).
275+
276+
**Kind**: inner method of [<code>Templating API: Attribute helpers</code>](#module_Templating API_ Attribute helpers)
277+
278+
| Param | Type |
279+
| --- | --- |
280+
| db | <code>\*</code> |
281+
| packageIds | <code>Array.&lt;number&gt;</code> |
282+
| clusterId | <code>number</code> |
283+
284+
<a name="module_Templating API_ Attribute helpers..if_cluster_has_feature_bitmap"></a>
285+
286+
### Templating API: Attribute helpers~if\_cluster\_has\_feature\_bitmap(options) ⇒ <code>Promise.&lt;string&gt;</code>
287+
Block helper that renders its body when the cluster in the current context
288+
defines a bitmap named 'Feature', and its inverse ({{else}}) when it does
289+
not. Intended for choosing between `using FeatureBitmapType = Feature;` and
290+
`using FeatureBitmapType = Clusters::StaticApplicationConfig::NoFeatureFlagsDefined;`
291+
in static-cluster-config headers.
292+
293+
Must be used inside a context that exposes a cluster `id` field, such as
294+
`zcl_clusters`, `selectedServerCluster`, or any block helper whose context
295+
object carries the ZCL cluster database ID as `id`.
296+
297+
**Kind**: inner method of [<code>Templating API: Attribute helpers</code>](#module_Templating API_ Attribute helpers)
298+
**Returns**: <code>Promise.&lt;string&gt;</code> - Rendered `fn` block when the cluster has a
299+
bitmap named 'Feature'; rendered `inverse` block otherwise.
300+
301+
| Param | Type | Description |
302+
| --- | --- | --- |
303+
| options | <code>\*</code> | Handlebars options object (fn / inverse blocks). |
304+
305+
**Example**
306+
```js
307+
// Inside a selectedServerCluster or zcl_clusters block:
308+
{{#if_cluster_has_feature_bitmap}}
309+
using FeatureBitmapType = Feature;
310+
{{else}}
311+
using FeatureBitmapType = Clusters::StaticApplicationConfig::NoFeatureFlagsDefined;
312+
{{/if_cluster_has_feature_bitmap}}
313+
```
314+
<a name="module_Templating API_ Attribute helpers..if_feature_bit_enabled"></a>
315+
316+
### Templating API: Attribute helpers~if\_feature\_bit\_enabled(options) ⇒ <code>string</code>
317+
Block helper that renders its body when the bitwise AND of `featureMapValue`
318+
and `mask` is non-zero (i.e. the specific feature bit is set), and its
319+
inverse ({{else}}) when the bit is clear.
320+
321+
Both arguments are parsed as integers so decimal strings (e.g. `"3"`) and
322+
hex strings (e.g. `"0x3"`) are accepted.
323+
324+
Combine with `cluster_feature_items` when you want to iterate over feature
325+
fields and selectively render only those that are enabled:
326+
{{#cluster_feature_items clusterCode}}
327+
{{#if_feature_bit_enabled featureMapValue mask}}...{{/if_feature_bit_enabled}}
328+
{{/cluster_feature_items}}
329+
330+
**Kind**: inner method of [<code>Templating API: Attribute helpers</code>](#module_Templating API_ Attribute helpers)
331+
**Returns**: <code>string</code> - Rendered `fn` block when `(featureMapValue & mask) !== 0`;
332+
rendered `inverse` block otherwise.
333+
**Given**: <code>string\|number</code> featureMapValue - The raw FeatureMap attribute default
334+
value for the current endpoint cluster (e.g. `"3"`).
335+
**Given**: <code>string\|number</code> mask - The bitmask of the feature field being tested
336+
(e.g. `1`).
337+
338+
| Param | Type | Description |
339+
| --- | --- | --- |
340+
| options | <code>\*</code> | Handlebars options object (fn / inverse blocks). |
341+
342+
**Example**
343+
```js
344+
// LevelControl, featureMap default = 3 (kOnOff | kLighting):
345+
{{#if_feature_bit_enabled "3" "1"}}enabled{{else}}disabled{{/if_feature_bit_enabled}}
346+
// → "enabled"
347+
{{#if_feature_bit_enabled "3" "4"}}enabled{{else}}disabled{{/if_feature_bit_enabled}}
348+
// → "disabled" (kFrequency bit 0x4 is not set)
349+
```
350+
<a name="module_Templating API_ Attribute helpers..cluster_feature_items"></a>
351+
352+
### Templating API: Attribute helpers~cluster\_feature\_items(options) ⇒ <code>Promise.&lt;string&gt;</code>
353+
Block helper that iterates over all fields of the Feature bitmap for a
354+
cluster identified by its ZCL cluster code, regardless of which bits are
355+
currently enabled. Use `if_feature_bit_enabled` inside the body to act on
356+
only those fields whose bit is set in a given FeatureMap value.
357+
358+
This is the preferred way to access Feature bitmap fields inside
359+
`user_cluster_attributes` because `zcl_bitmaps` requires a cluster database
360+
`id` in context that is not available there. This helper performs the cluster
361+
lookup by ZCL code (not name) for robustness.
362+
363+
Each iteration context exposes:
364+
- `name` {string} field name as stored in the ZCL database (e.g. `"kOnOff"`)
365+
- `label` {string} same as `name`
366+
- `mask` {number} the field's bitmask (e.g. `1`)
367+
368+
If the cluster has no bitmap named 'Feature' the body is never rendered.
369+
370+
**Kind**: inner method of [<code>Templating API: Attribute helpers</code>](#module_Templating API_ Attribute helpers)
371+
**Returns**: <code>Promise.&lt;string&gt;</code> - Concatenated rendered blocks for each feature field.
372+
**Given**: <code>string\|number</code> clusterCode - The ZCL cluster code (e.g. `8` for
373+
LevelControl). Inside `user_cluster_attributes` pass `../code` to
374+
reference the enclosing `user_clusters` cluster code.
375+
376+
| Param | Type | Description |
377+
| --- | --- | --- |
378+
| options | <code>\*</code> | Handlebars options object. |
379+
380+
**Example**
381+
```js
382+
// List only enabled feature bits for LevelControl (featureMap default = 3):
383+
{{#if (is_str_equal name "FeatureMap")}}
384+
{{#cluster_feature_items ../code}}
385+
{{#if_feature_bit_enabled ../defaultValue mask}}
386+
FeatureBitmapType::k{{asUpperCamelCase label preserveAcronyms=true}}, // feature bit {{as_hex mask}}
387+
{{/if_feature_bit_enabled}}
388+
{{/cluster_feature_items}}
389+
{{/if}}
390+
// Emits: FeatureBitmapType::kOnOff, // feature bit 0x1
391+
// FeatureBitmapType::kLighting, // feature bit 0x2
392+
// Skips kFrequency (mask 0x4 not set in value 3)
393+
```
394+
**Example**
395+
```js
396+
// List ALL defined feature bits regardless of enabled state:
397+
{{#cluster_feature_items clusterCode}}
398+
{{label}}: {{as_hex mask}}
399+
{{/cluster_feature_items}}
400+
```
264401
<a name="module_Templating API_ C formatting helpers"></a>
265402

266403
## Templating API: C formatting helpers

0 commit comments

Comments
 (0)