@wix/himalaya-cli 0.1407.0 → 0.1408.0
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/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/builder.d.ts +1 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/schema.d.ts +4 -0
- package/dist/cli.mjs +41 -30
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/component-reference.json +1 -1
- package/guides/component-reference.md +4 -0
- package/package.json +2 -2
- package/templates/beauty-salon-owner/dev/index.ts +49 -30
- package/templates/beauty-salon-owner/tier5-src/_shared/aria-chat.ts +8 -6
- package/templates/beauty-salon-owner/tier5-src/_shared/aria-widget-model.ts +84 -1
- package/templates/beauty-salon-owner/tier5-src/_shared/aria-widget-view.ts +34 -13
- package/templates/community-club-owner/dev/index.ts +49 -30
- package/templates/community-club-owner/tier5-src/_shared/aria-chat.ts +8 -6
- package/templates/community-club-owner/tier5-src/_shared/aria-widget-model.ts +84 -1
- package/templates/community-club-owner/tier5-src/_shared/aria-widget-view.ts +34 -13
- package/templates/events-meetups-owner/dev/index.ts +49 -30
- package/templates/events-meetups-owner/tier5-src/_shared/aria-chat.ts +8 -6
- package/templates/events-meetups-owner/tier5-src/_shared/aria-widget-model.ts +84 -1
- package/templates/events-meetups-owner/tier5-src/_shared/aria-widget-view.ts +34 -13
- package/templates/gym-fitness-owner/dev/index.ts +49 -30
- package/templates/gym-fitness-owner/tier5-src/_shared/aria-chat.ts +8 -6
- package/templates/gym-fitness-owner/tier5-src/_shared/aria-widget-model.ts +84 -1
- package/templates/gym-fitness-owner/tier5-src/_shared/aria-widget-view.ts +34 -13
- package/templates/nonprofit-cause-owner/dev/index.ts +49 -30
- package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-chat.ts +8 -6
- package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-widget-model.ts +84 -1
- package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-widget-view.ts +34 -13
- package/templates/owner-lite/dev/index.ts +49 -30
- package/templates/owner-lite/tier5-src/_shared/aria-chat.ts +8 -6
- package/templates/owner-lite/tier5-src/_shared/aria-widget-model.ts +84 -1
- package/templates/owner-lite/tier5-src/_shared/aria-widget-view.ts +34 -13
- package/templates/podcast-creator-owner/dev/index.ts +49 -30
- package/templates/podcast-creator-owner/tier5-src/_shared/aria-chat.ts +8 -6
- package/templates/podcast-creator-owner/tier5-src/_shared/aria-widget-model.ts +84 -1
- package/templates/podcast-creator-owner/tier5-src/_shared/aria-widget-view.ts +34 -13
- package/templates/portfolio-creative-owner/dev/index.ts +49 -30
- package/templates/portfolio-creative-owner/tier5-src/_shared/aria-chat.ts +8 -6
- package/templates/portfolio-creative-owner/tier5-src/_shared/aria-widget-model.ts +84 -1
- package/templates/portfolio-creative-owner/tier5-src/_shared/aria-widget-view.ts +34 -13
- package/templates/restaurant-owner/dev/index.ts +49 -30
- package/templates/restaurant-owner/tier5-src/_shared/aria-chat.ts +8 -6
- package/templates/restaurant-owner/tier5-src/_shared/aria-widget-model.ts +84 -1
- package/templates/restaurant-owner/tier5-src/_shared/aria-widget-view.ts +34 -13
- package/templates/retail-store-owner/dev/index.ts +49 -30
- package/templates/retail-store-owner/tier5-src/_shared/aria-chat.ts +8 -6
- package/templates/retail-store-owner/tier5-src/_shared/aria-widget-model.ts +84 -1
- package/templates/retail-store-owner/tier5-src/_shared/aria-widget-view.ts +34 -13
- package/templates/yoga-studio-owner/dev/index.ts +49 -30
- package/templates/yoga-studio-owner/tier5-src/_shared/aria-chat.ts +8 -6
- package/templates/yoga-studio-owner/tier5-src/_shared/aria-widget-model.ts +84 -1
- package/templates/yoga-studio-owner/tier5-src/_shared/aria-widget-view.ts +34 -13
|
@@ -57241,7 +57241,7 @@ const SCREENS = runtimeSetting({
|
|
|
57241
57241
|
"height": 44,
|
|
57242
57242
|
"shape": "rounded",
|
|
57243
57243
|
"contentMode": "fill",
|
|
57244
|
-
"contentDescription": "$item.
|
|
57244
|
+
"contentDescription": "$item.label"
|
|
57245
57245
|
}
|
|
57246
57246
|
},
|
|
57247
57247
|
"modifiers": {
|
|
@@ -57249,6 +57249,7 @@ const SCREENS = runtimeSetting({
|
|
|
57249
57249
|
}
|
|
57250
57250
|
},
|
|
57251
57251
|
"title": "$item.title",
|
|
57252
|
+
"markdown": true,
|
|
57252
57253
|
"subtitle": "$item.subtitle",
|
|
57253
57254
|
"trailing": {
|
|
57254
57255
|
"id": "himi_owner_lite_aria.widget.SINGLE_SELECT.pick_$item.id",
|
|
@@ -57513,7 +57514,7 @@ const SCREENS = runtimeSetting({
|
|
|
57513
57514
|
}
|
|
57514
57515
|
},
|
|
57515
57516
|
"modifiers": {
|
|
57516
|
-
"accessibilityLabel": "$item.
|
|
57517
|
+
"accessibilityLabel": "$item.label"
|
|
57517
57518
|
}
|
|
57518
57519
|
},
|
|
57519
57520
|
{
|
|
@@ -57527,7 +57528,7 @@ const SCREENS = runtimeSetting({
|
|
|
57527
57528
|
"height": 36,
|
|
57528
57529
|
"shape": "rounded",
|
|
57529
57530
|
"contentMode": "fill",
|
|
57530
|
-
"contentDescription": "$item.
|
|
57531
|
+
"contentDescription": "$item.label"
|
|
57531
57532
|
}
|
|
57532
57533
|
},
|
|
57533
57534
|
"modifiers": {
|
|
@@ -57550,7 +57551,8 @@ const SCREENS = runtimeSetting({
|
|
|
57550
57551
|
"props": {
|
|
57551
57552
|
"text": "$item.title",
|
|
57552
57553
|
"style": "body",
|
|
57553
|
-
"maxLines": 2
|
|
57554
|
+
"maxLines": 2,
|
|
57555
|
+
"markdown": true
|
|
57554
57556
|
}
|
|
57555
57557
|
}
|
|
57556
57558
|
},
|
|
@@ -57563,7 +57565,8 @@ const SCREENS = runtimeSetting({
|
|
|
57563
57565
|
"text": "$item.subtitle",
|
|
57564
57566
|
"style": "footnote",
|
|
57565
57567
|
"color": "textSecondary",
|
|
57566
|
-
"maxLines": 2
|
|
57568
|
+
"maxLines": 2,
|
|
57569
|
+
"markdown": true
|
|
57567
57570
|
}
|
|
57568
57571
|
},
|
|
57569
57572
|
"modifiers": {
|
|
@@ -57631,7 +57634,7 @@ const SCREENS = runtimeSetting({
|
|
|
57631
57634
|
"aspectRatio": 1,
|
|
57632
57635
|
"shape": "rounded",
|
|
57633
57636
|
"contentMode": "fill",
|
|
57634
|
-
"contentDescription": "$item.
|
|
57637
|
+
"contentDescription": "$item.label"
|
|
57635
57638
|
}
|
|
57636
57639
|
},
|
|
57637
57640
|
"modifiers": {
|
|
@@ -57663,7 +57666,7 @@ const SCREENS = runtimeSetting({
|
|
|
57663
57666
|
}
|
|
57664
57667
|
},
|
|
57665
57668
|
"modifiers": {
|
|
57666
|
-
"accessibilityLabel": "$item.
|
|
57669
|
+
"accessibilityLabel": "$item.label"
|
|
57667
57670
|
}
|
|
57668
57671
|
},
|
|
57669
57672
|
{
|
|
@@ -57682,7 +57685,8 @@ const SCREENS = runtimeSetting({
|
|
|
57682
57685
|
"props": {
|
|
57683
57686
|
"text": "$item.title",
|
|
57684
57687
|
"style": "body",
|
|
57685
|
-
"maxLines": 2
|
|
57688
|
+
"maxLines": 2,
|
|
57689
|
+
"markdown": true
|
|
57686
57690
|
}
|
|
57687
57691
|
}
|
|
57688
57692
|
},
|
|
@@ -57695,7 +57699,8 @@ const SCREENS = runtimeSetting({
|
|
|
57695
57699
|
"text": "$item.subtitle",
|
|
57696
57700
|
"style": "footnote",
|
|
57697
57701
|
"color": "textSecondary",
|
|
57698
|
-
"maxLines": 2
|
|
57702
|
+
"maxLines": 2,
|
|
57703
|
+
"markdown": true
|
|
57699
57704
|
}
|
|
57700
57705
|
},
|
|
57701
57706
|
"modifiers": {
|
|
@@ -58146,7 +58151,7 @@ const SCREENS = runtimeSetting({
|
|
|
58146
58151
|
}
|
|
58147
58152
|
},
|
|
58148
58153
|
"modifiers": {
|
|
58149
|
-
"accessibilityLabel": "$item.
|
|
58154
|
+
"accessibilityLabel": "$item.label"
|
|
58150
58155
|
}
|
|
58151
58156
|
},
|
|
58152
58157
|
{
|
|
@@ -58160,7 +58165,7 @@ const SCREENS = runtimeSetting({
|
|
|
58160
58165
|
"height": 36,
|
|
58161
58166
|
"shape": "rounded",
|
|
58162
58167
|
"contentMode": "fill",
|
|
58163
|
-
"contentDescription": "$item.
|
|
58168
|
+
"contentDescription": "$item.label"
|
|
58164
58169
|
}
|
|
58165
58170
|
},
|
|
58166
58171
|
"modifiers": {
|
|
@@ -58183,7 +58188,8 @@ const SCREENS = runtimeSetting({
|
|
|
58183
58188
|
"props": {
|
|
58184
58189
|
"text": "$item.title",
|
|
58185
58190
|
"style": "body",
|
|
58186
|
-
"maxLines": 2
|
|
58191
|
+
"maxLines": 2,
|
|
58192
|
+
"markdown": true
|
|
58187
58193
|
}
|
|
58188
58194
|
}
|
|
58189
58195
|
},
|
|
@@ -58196,7 +58202,8 @@ const SCREENS = runtimeSetting({
|
|
|
58196
58202
|
"text": "$item.subtitle",
|
|
58197
58203
|
"style": "footnote",
|
|
58198
58204
|
"color": "textSecondary",
|
|
58199
|
-
"maxLines": 2
|
|
58205
|
+
"maxLines": 2,
|
|
58206
|
+
"markdown": true
|
|
58200
58207
|
}
|
|
58201
58208
|
},
|
|
58202
58209
|
"modifiers": {
|
|
@@ -58435,7 +58442,8 @@ const SCREENS = runtimeSetting({
|
|
|
58435
58442
|
"props": {
|
|
58436
58443
|
"text": "$item.title",
|
|
58437
58444
|
"style": "bodyEmphasis",
|
|
58438
|
-
"maxLines": 2
|
|
58445
|
+
"maxLines": 2,
|
|
58446
|
+
"markdown": true
|
|
58439
58447
|
}
|
|
58440
58448
|
}
|
|
58441
58449
|
},
|
|
@@ -58447,7 +58455,8 @@ const SCREENS = runtimeSetting({
|
|
|
58447
58455
|
"props": {
|
|
58448
58456
|
"text": "$item.subtitle",
|
|
58449
58457
|
"style": "title3",
|
|
58450
|
-
"maxLines": 1
|
|
58458
|
+
"maxLines": 1,
|
|
58459
|
+
"markdown": true
|
|
58451
58460
|
}
|
|
58452
58461
|
},
|
|
58453
58462
|
"modifiers": {
|
|
@@ -58532,7 +58541,8 @@ const SCREENS = runtimeSetting({
|
|
|
58532
58541
|
"props": {
|
|
58533
58542
|
"text": "$item.text",
|
|
58534
58543
|
"style": "footnote",
|
|
58535
|
-
"maxLines": 8
|
|
58544
|
+
"maxLines": 8,
|
|
58545
|
+
"markdown": true
|
|
58536
58546
|
}
|
|
58537
58547
|
},
|
|
58538
58548
|
"modifiers": {
|
|
@@ -58977,7 +58987,7 @@ const SCREENS = runtimeSetting({
|
|
|
58977
58987
|
"fillWidth": true,
|
|
58978
58988
|
"aspectRatio": 1.5,
|
|
58979
58989
|
"contentMode": "fill",
|
|
58980
|
-
"contentDescription": "$item.
|
|
58990
|
+
"contentDescription": "$item.label"
|
|
58981
58991
|
}
|
|
58982
58992
|
},
|
|
58983
58993
|
"modifiers": {
|
|
@@ -59038,7 +59048,8 @@ const SCREENS = runtimeSetting({
|
|
|
59038
59048
|
"type": "Text",
|
|
59039
59049
|
"props": {
|
|
59040
59050
|
"text": "$item.title",
|
|
59041
|
-
"style": "bodyEmphasis"
|
|
59051
|
+
"style": "bodyEmphasis",
|
|
59052
|
+
"markdown": true
|
|
59042
59053
|
}
|
|
59043
59054
|
}
|
|
59044
59055
|
},
|
|
@@ -59050,7 +59061,8 @@ const SCREENS = runtimeSetting({
|
|
|
59050
59061
|
"props": {
|
|
59051
59062
|
"text": "$item.subtitle",
|
|
59052
59063
|
"style": "body",
|
|
59053
|
-
"color": "textSecondary"
|
|
59064
|
+
"color": "textSecondary",
|
|
59065
|
+
"markdown": true
|
|
59054
59066
|
}
|
|
59055
59067
|
},
|
|
59056
59068
|
"modifiers": {
|
|
@@ -59064,7 +59076,8 @@ const SCREENS = runtimeSetting({
|
|
|
59064
59076
|
"type": "Text",
|
|
59065
59077
|
"props": {
|
|
59066
59078
|
"text": "$item.text",
|
|
59067
|
-
"style": "body"
|
|
59079
|
+
"style": "body",
|
|
59080
|
+
"markdown": true
|
|
59068
59081
|
}
|
|
59069
59082
|
},
|
|
59070
59083
|
"modifiers": {
|
|
@@ -59078,7 +59091,8 @@ const SCREENS = runtimeSetting({
|
|
|
59078
59091
|
"type": "Text",
|
|
59079
59092
|
"props": {
|
|
59080
59093
|
"text": "$item.listText",
|
|
59081
|
-
"style": "body"
|
|
59094
|
+
"style": "body",
|
|
59095
|
+
"markdown": true
|
|
59082
59096
|
}
|
|
59083
59097
|
},
|
|
59084
59098
|
"modifiers": {
|
|
@@ -59286,7 +59300,7 @@ const SCREENS = runtimeSetting({
|
|
|
59286
59300
|
"height": 36,
|
|
59287
59301
|
"shape": "rounded",
|
|
59288
59302
|
"contentMode": "fill",
|
|
59289
|
-
"contentDescription": "$item.
|
|
59303
|
+
"contentDescription": "$item.label"
|
|
59290
59304
|
}
|
|
59291
59305
|
},
|
|
59292
59306
|
"modifiers": {
|
|
@@ -59294,6 +59308,7 @@ const SCREENS = runtimeSetting({
|
|
|
59294
59308
|
}
|
|
59295
59309
|
},
|
|
59296
59310
|
"title": "$item.title",
|
|
59311
|
+
"markdown": true,
|
|
59297
59312
|
"subtitle": "$item.subtitle",
|
|
59298
59313
|
"onTap": {
|
|
59299
59314
|
"actionId": "tier5.himiOwnerLiteAria.widgetPick",
|
|
@@ -59537,7 +59552,7 @@ const SCREENS = runtimeSetting({
|
|
|
59537
59552
|
}
|
|
59538
59553
|
},
|
|
59539
59554
|
"modifiers": {
|
|
59540
|
-
"accessibilityLabel": "$item.
|
|
59555
|
+
"accessibilityLabel": "$item.label"
|
|
59541
59556
|
}
|
|
59542
59557
|
},
|
|
59543
59558
|
{
|
|
@@ -59551,7 +59566,7 @@ const SCREENS = runtimeSetting({
|
|
|
59551
59566
|
"height": 36,
|
|
59552
59567
|
"shape": "rounded",
|
|
59553
59568
|
"contentMode": "fill",
|
|
59554
|
-
"contentDescription": "$item.
|
|
59569
|
+
"contentDescription": "$item.label"
|
|
59555
59570
|
}
|
|
59556
59571
|
},
|
|
59557
59572
|
"modifiers": {
|
|
@@ -59895,7 +59910,7 @@ const SCREENS = runtimeSetting({
|
|
|
59895
59910
|
}
|
|
59896
59911
|
},
|
|
59897
59912
|
"modifiers": {
|
|
59898
|
-
"accessibilityLabel": "$item.
|
|
59913
|
+
"accessibilityLabel": "$item.label"
|
|
59899
59914
|
}
|
|
59900
59915
|
},
|
|
59901
59916
|
{
|
|
@@ -59914,7 +59929,8 @@ const SCREENS = runtimeSetting({
|
|
|
59914
59929
|
"props": {
|
|
59915
59930
|
"text": "$item.title",
|
|
59916
59931
|
"style": "body",
|
|
59917
|
-
"maxLines": 2
|
|
59932
|
+
"maxLines": 2,
|
|
59933
|
+
"markdown": true
|
|
59918
59934
|
}
|
|
59919
59935
|
}
|
|
59920
59936
|
},
|
|
@@ -59927,7 +59943,8 @@ const SCREENS = runtimeSetting({
|
|
|
59927
59943
|
"text": "$item.subtitle",
|
|
59928
59944
|
"style": "footnote",
|
|
59929
59945
|
"color": "textSecondary",
|
|
59930
|
-
"maxLines": 2
|
|
59946
|
+
"maxLines": 2,
|
|
59947
|
+
"markdown": true
|
|
59931
59948
|
}
|
|
59932
59949
|
},
|
|
59933
59950
|
"modifiers": {
|
|
@@ -59991,7 +60008,7 @@ const SCREENS = runtimeSetting({
|
|
|
59991
60008
|
}
|
|
59992
60009
|
},
|
|
59993
60010
|
"modifiers": {
|
|
59994
|
-
"accessibilityLabel": "$item.
|
|
60011
|
+
"accessibilityLabel": "$item.label"
|
|
59995
60012
|
}
|
|
59996
60013
|
},
|
|
59997
60014
|
{
|
|
@@ -60010,7 +60027,8 @@ const SCREENS = runtimeSetting({
|
|
|
60010
60027
|
"props": {
|
|
60011
60028
|
"text": "$item.title",
|
|
60012
60029
|
"style": "body",
|
|
60013
|
-
"maxLines": 2
|
|
60030
|
+
"maxLines": 2,
|
|
60031
|
+
"markdown": true
|
|
60014
60032
|
}
|
|
60015
60033
|
}
|
|
60016
60034
|
},
|
|
@@ -60023,7 +60041,8 @@ const SCREENS = runtimeSetting({
|
|
|
60023
60041
|
"text": "$item.subtitle",
|
|
60024
60042
|
"style": "footnote",
|
|
60025
60043
|
"color": "textSecondary",
|
|
60026
|
-
"maxLines": 2
|
|
60044
|
+
"maxLines": 2,
|
|
60045
|
+
"markdown": true
|
|
60027
60046
|
}
|
|
60028
60047
|
},
|
|
60029
60048
|
"modifiers": {
|
|
@@ -77,7 +77,7 @@ import type { FileHandle } from "@himalaya/sdk-types";
|
|
|
77
77
|
import { createAriaUploadQueue } from "./aria-upload-queue.js";
|
|
78
78
|
import { runClientToolExchange, type AriaClientTools, type ConsentMemory } from "./aria-client-tools.js";
|
|
79
79
|
import { proseOfParts, scanEnvelopes, stripHidden } from "./aria-widgets.js";
|
|
80
|
-
import { isWebUrl, stripMarkdown } from "./aria-widget-model.js";
|
|
80
|
+
import { drawnText, isWebUrl, stripMarkdown } from "./aria-widget-model.js";
|
|
81
81
|
import {
|
|
82
82
|
DEFAULT_QUESTIONNAIRE_COPY,
|
|
83
83
|
NO_WIDGET,
|
|
@@ -86,6 +86,7 @@ import {
|
|
|
86
86
|
questionnaireAnswers,
|
|
87
87
|
questionnaireSynced,
|
|
88
88
|
sameQuestionnaire,
|
|
89
|
+
withLabels,
|
|
89
90
|
type QuestionnaireCopy,
|
|
90
91
|
type SubtreeSlot,
|
|
91
92
|
type WidgetOptionRow,
|
|
@@ -2573,7 +2574,7 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
|
|
|
2573
2574
|
const withWidgetQuery = (w: WidgetView, query: string): WidgetView => {
|
|
2574
2575
|
const needle = query.toLowerCase();
|
|
2575
2576
|
const suggestions = !needle ? w.options : w.options.filter((option) =>
|
|
2576
|
-
|
|
2577
|
+
[option.title, option.subtitle, option.text].map(drawnText).join(" ").toLowerCase().includes(needle));
|
|
2577
2578
|
return { ...w, query, suggestions, suggestionsEmpty: suggestions.length === 0,
|
|
2578
2579
|
noMatches: !!needle && suggestions.length === 0 };
|
|
2579
2580
|
};
|
|
@@ -2693,7 +2694,7 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
|
|
|
2693
2694
|
options = items.map((item, i) => {
|
|
2694
2695
|
const pictureUrl = isWixMediaHost(hostOf(item.imageUrl)) ? item.imageUrl : "";
|
|
2695
2696
|
return {
|
|
2696
|
-
id: `o${i}`, value: item.id, title: item.title, subtitle: item.subtitle,
|
|
2697
|
+
id: `o${i}`, value: item.id, title: item.title, label: item.title, subtitle: item.subtitle,
|
|
2697
2698
|
subtitleHidden: !item.subtitle, text: "", textHidden: true, badge: "", badgeHidden: true,
|
|
2698
2699
|
pictureUrl, pictureHidden: !pictureUrl, buttonLabel: "", buttonHidden: true,
|
|
2699
2700
|
listText: "", benefits: [], listHidden: true, selected: false, respondText: "",
|
|
@@ -3599,7 +3600,8 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
|
|
|
3599
3600
|
// Transcript scroll — a conversation rehydrated with no send token (state persisted
|
|
3600
3601
|
// before tokens existed) still opens at its latest turn.
|
|
3601
3602
|
const opened = s.scrollSend || isGreetingOnly(messages) ? {} : openedAtLatest(s, messages);
|
|
3602
|
-
const reused: AriaChatState = { ...s, status: "ready", messages, prompts: promptsFor(messages, chipsOf(s)), ...opened
|
|
3603
|
+
const reused: AriaChatState = { ...s, status: "ready", messages, prompts: promptsFor(messages, chipsOf(s)), ...opened,
|
|
3604
|
+
...(s.widget ? { widget: withLabels(s.widget) } : {}) };
|
|
3603
3605
|
// A persisted state can be waiting on a fetch that died with the previous
|
|
3604
3606
|
// process; nothing would ever settle it, so ask again. And one minted by a
|
|
3605
3607
|
// bundle from before the suggestions existed never asked at all — the
|
|
@@ -4081,8 +4083,8 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
|
|
|
4081
4083
|
: questionnaire
|
|
4082
4084
|
? [questionnaireAnswers(w)].filter(Boolean)
|
|
4083
4085
|
: option && !option.selected
|
|
4084
|
-
? [option.title || option.value]
|
|
4085
|
-
: w.options.filter((o) => o.selected).map((o) => o.title || o.value);
|
|
4086
|
+
? [option.label || option.title || option.value]
|
|
4087
|
+
: w.options.filter((o) => o.selected).map((o) => o.label || o.title || o.value);
|
|
4086
4088
|
const content = substituteSelection(template, selected).trim();
|
|
4087
4089
|
if (!content) return s;
|
|
4088
4090
|
if (duplicate(s, content)) return s;
|
|
@@ -210,6 +210,88 @@ export function stripMarkdown(src: string): string {
|
|
|
210
210
|
return t.trim();
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
+
/** A literal `*` in prose drawn with `markdown: true`. Web and Android pair any two
|
|
214
|
+
* asterisks (`2*4 *Pine*` would italicise `4 `) and neither honours a backslash
|
|
215
|
+
* escape, so a star that is not part of emphasis is drawn as U+2217, which looks
|
|
216
|
+
* the same and parses as nothing. `drawnText` maps it back. The trailing word
|
|
217
|
+
* joiner (invisible) is what tells it apart from a U+2217 the prose already had:
|
|
218
|
+
* `emphasisMarkdown` drops a joiner that follows one in its input, so only a
|
|
219
|
+
* sentinel carries it. */
|
|
220
|
+
const LITERAL_STAR = "\u2217\u2060";
|
|
221
|
+
/** An underscore inside a code span, parked until emphasis has been read. */
|
|
222
|
+
const CODE_UNDERSCORE = "\u0005";
|
|
223
|
+
|
|
224
|
+
/** `stripMarkdown`, keeping inline emphasis.
|
|
225
|
+
*
|
|
226
|
+
* Option prose is drawn by `Text(markdown: true)` / `ListItem(markdown: true)`,
|
|
227
|
+
* so bold and italic can survive — everything else is stripped as `stripMarkdown`
|
|
228
|
+
* strips it. Emphasis is re-emitted as `**x**` / `*x*` only: web's parser has no
|
|
229
|
+
* underscore syntax and Android's needs word boundaries, so one spelling is the
|
|
230
|
+
* only one every renderer agrees on. Nested emphasis keeps its outer run only,
|
|
231
|
+
* because neither of those parsers pairs `***x***`.
|
|
232
|
+
*
|
|
233
|
+
* Nothing a renderer would turn into a link survives: links and images are
|
|
234
|
+
* unwrapped until none is left (a nested `[[a](x)](tel:…)` would otherwise
|
|
235
|
+
* rebuild one) and `<scheme:…>` autolinks lose their brackets. Every asterisk
|
|
236
|
+
* left over is a `LITERAL_STAR`, so no marker the renderers could mis-pair is
|
|
237
|
+
* ever emitted. `drawnText` of the result is the text the row shows. */
|
|
238
|
+
export function emphasisMarkdown(src: string): string {
|
|
239
|
+
if (!stripMarkdown(src)) return "";
|
|
240
|
+
const BOLD_OPEN = "\u0001", BOLD_CLOSE = "\u0002", EM_OPEN = "\u0003", EM_CLOSE = "\u0004";
|
|
241
|
+
// Inside a run, a paired nested marker is dropped (the outer run wins) and a lone star
|
|
242
|
+
// is content — it survives as a literal one. Double before single, or the inner
|
|
243
|
+
// `*x*` of `_**x**_` is read as the italic and its outer stars are left over.
|
|
244
|
+
const flat = (inner: string) => inner.replace(/[\u0001-\u0004]/g, "")
|
|
245
|
+
.replace(/\*\*([^*\n]+)\*\*/g, "$1").replace(/\*([^*\n]+)\*/g, "$1");
|
|
246
|
+
const bold = (inner: string) => `${BOLD_OPEN}${flat(inner)}${BOLD_CLOSE}`;
|
|
247
|
+
const em = (inner: string) => `${EM_OPEN}${flat(inner)}${EM_CLOSE}`;
|
|
248
|
+
let t = src.replace(/[\u0001-\u0005]/g, "").replace(/\u2217\u2060/g, "\u2217");
|
|
249
|
+
t = t.replace(/```[a-zA-Z0-9]*\n?/g, "").replace(/```/g, "");
|
|
250
|
+
// A code span is never read as emphasis: its paired markers are dropped, as
|
|
251
|
+
// `stripMarkdown` drops them, and whatever is left is parked so no prose marker
|
|
252
|
+
// can pair with it.
|
|
253
|
+
t = t.replace(/`([^`]+)`/g, (_, x: string) => x
|
|
254
|
+
.replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*]+)\*/g, "$1")
|
|
255
|
+
.replace(/__([^_]+)__/g, "$1").replace(/_([^_]+)_/g, "$1")
|
|
256
|
+
.replace(/\*/g, LITERAL_STAR).replace(/_/g, CODE_UNDERSCORE));
|
|
257
|
+
for (let prev = ""; prev !== t;) {
|
|
258
|
+
prev = t;
|
|
259
|
+
t = t.replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\[([^\]]+)\]\([^)]*\)/g, "$1");
|
|
260
|
+
}
|
|
261
|
+
t = t.replace(/<([a-zA-Z][a-zA-Z0-9+.-]*:[^>\s]*)>/g, "$1");
|
|
262
|
+
// Line-level markup first, so a bullet's or a rule's `*` is gone before emphasis is read.
|
|
263
|
+
t = t.replace(/^#{1,6}\s+/gm, "");
|
|
264
|
+
t = t.replace(/^>\s?/gm, "");
|
|
265
|
+
t = t.replace(/^\s*([-*_])\1{2,}\s*$/gm, "");
|
|
266
|
+
t = t.replace(/^\s*[-*+]\s+/gm, "• ");
|
|
267
|
+
// Emphasis, strictly delimited (no space just inside a marker), parked behind control
|
|
268
|
+
// characters. Bold may contain single stars — an inner italic — which it drops.
|
|
269
|
+
// Underscores first, so an asterisk run around them absorbs them. Only at word
|
|
270
|
+
// boundaries, as CommonMark reads them: an identifier like `snake_case_name` is
|
|
271
|
+
// not italic.
|
|
272
|
+
// An underscore between two word characters is content, so `_foo_bar_` is one run.
|
|
273
|
+
t = t.replace(/(^|[^\w])__(?=\S)((?:[^_\n]|(?<=\w)_(?=\w))*?[^\s_])__(?!\w)/g, (_, pre, x) => pre + bold(x));
|
|
274
|
+
t = t.replace(/(^|[^\w])_(?=\S)((?:[^_\n]|(?<=\w)_(?=\w))*?[^\s_])_(?!\w)/g, (_, pre, x) => pre + em(x));
|
|
275
|
+
t = t.replace(/\*\*\*(?=\S)([^*\n]*?\S)\*\*\*/g, (_, x) => bold(x));
|
|
276
|
+
t = t.replace(/\*\*(?=[^\s*])((?:[^*\n]|\*(?!\*))*?[^\s*])\*\*/g, (_, x) => bold(x));
|
|
277
|
+
t = t.replace(/(^|[^\w*])\*(?=[^\s*])([^*\n]*?[^\s*])\*(?![\w*])/g, (_, pre, x) => pre + em(x));
|
|
278
|
+
t = t.replace(/\n{3,}/g, "\n\n");
|
|
279
|
+
t = t.replace(/\*/g, LITERAL_STAR).replace(new RegExp(CODE_UNDERSCORE, "g"), "_");
|
|
280
|
+
t = t.replace(/\u0001([^\u0002]*)\u0002/g, "**$1**").replace(/\u0003([^\u0004]*)\u0004/g, "*$1*");
|
|
281
|
+
// (A literal star inside a run was converted with the rest, before the run's own
|
|
282
|
+
// markers were written back.)
|
|
283
|
+
return t.trim();
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/** What a row drawn with `markdown: true` shows for `emphasisMarkdown` output: the
|
|
287
|
+
* text with its `**x**` / `*x*` markers removed and literal stars restored. The
|
|
288
|
+
* accessibility name and the search haystack use this, so they say exactly what
|
|
289
|
+
* is on screen. */
|
|
290
|
+
export function drawnText(s: string): string {
|
|
291
|
+
return (s || "").replace(/\*\*([^*\n]+)\*\*/g, "$1").replace(/\*([^*\n]+)\*/g, "$1")
|
|
292
|
+
.replace(new RegExp(LITERAL_STAR, "g"), "*");
|
|
293
|
+
}
|
|
294
|
+
|
|
213
295
|
/** A display string, whether the wire wrote it bare or wrapped.
|
|
214
296
|
*
|
|
215
297
|
* QUESTIONNAIRE writes every label as `{ text: "…" }` — question titles,
|
|
@@ -323,7 +405,8 @@ export function optionsOf(o: Record<string, unknown> | null): WidgetOption[] {
|
|
|
323
405
|
const color = stringAt(spec, "color");
|
|
324
406
|
const hex = /^#[0-9a-f]{6}$/i.test(color);
|
|
325
407
|
const tint = hex ? "accentPrimary" : !name || name === "Confirm" ? "success" : "textPrimary";
|
|
326
|
-
|
|
408
|
+
// Drawn with `markdown: true`, like the option prose above it.
|
|
409
|
+
return { text: emphasisMarkdown(textOf(entry)),
|
|
327
410
|
icon: name === "Gift" ? "gift" : name === "Send" ? "paper_plane" : "check",
|
|
328
411
|
color: tint, colorHex: hex ? color : "",
|
|
329
412
|
successHidden: tint !== "success", plainHidden: tint !== "textPrimary", customHidden: tint !== "accentPrimary" };
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// the transcript bubbles already use for their three link slots.
|
|
14
14
|
|
|
15
15
|
import type { NormalizedWidget, WidgetBenefit, WidgetKind, WidgetOption } from "./aria-widget-model.js";
|
|
16
|
-
import { SELECTED_TOKEN, VALUES_TOKEN, isWebUrl, stripMarkdown } from "./aria-widget-model.js";
|
|
16
|
+
import { SELECTED_TOKEN, VALUES_TOKEN, drawnText, emphasisMarkdown, isWebUrl, stripMarkdown } from "./aria-widget-model.js";
|
|
17
17
|
import { oauthView } from "./aria-widget-oauth.js";
|
|
18
18
|
import { composeGenericCard } from "./aria-generic-widget.js";
|
|
19
19
|
import { formatNumber } from "./engine-intl.js";
|
|
@@ -81,7 +81,11 @@ export interface WidgetRow {
|
|
|
81
81
|
export interface WidgetOptionRow {
|
|
82
82
|
id: string;
|
|
83
83
|
value: string;
|
|
84
|
+
/** Drawn prose: inline emphasis kept (`**x**` / `*x*`), parsed by `markdown: true`. */
|
|
84
85
|
title: string;
|
|
86
|
+
/** `title` stripped to plain text — the accessibility name, the search haystack,
|
|
87
|
+
* and anything echoed back as text. */
|
|
88
|
+
label: string;
|
|
85
89
|
subtitle: string;
|
|
86
90
|
subtitleHidden: boolean;
|
|
87
91
|
text: string;
|
|
@@ -400,7 +404,7 @@ export const DEFAULT_QUESTIONNAIRE_COPY: QuestionnaireCopy = {
|
|
|
400
404
|
/** A question's answer as the owner would say it: the chosen choices' titles,
|
|
401
405
|
* then anything typed. Empty when unanswered. */
|
|
402
406
|
function answerOf(q: WidgetQuestion): string {
|
|
403
|
-
const parts = q.choices.filter((c) => c.selected).map((c) => c.title || c.value);
|
|
407
|
+
const parts = q.choices.filter((c) => c.selected).map((c) => c.label || c.title || c.value);
|
|
404
408
|
const typed = q.freeText.trim();
|
|
405
409
|
if (typed) parts.push(typed);
|
|
406
410
|
return parts.join(", ");
|
|
@@ -648,23 +652,26 @@ function optionRow(
|
|
|
648
652
|
// raw `text` is still exported below for anything that wants both.
|
|
649
653
|
// "Has a title" is judged on the STRIPPED title: a title of pure markup (`***`) falls back
|
|
650
654
|
// to the option's other prose exactly as a missing one does.
|
|
651
|
-
const
|
|
652
|
-
const
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
//
|
|
658
|
-
//
|
|
659
|
-
//
|
|
660
|
-
const
|
|
661
|
-
const
|
|
655
|
+
const hasTitle = !!stripMarkdown(o.title);
|
|
656
|
+
const titleSrc = hasTitle ? o.title : (o.text || o.subtitle);
|
|
657
|
+
const subtitleSrc = hasTitle ? (o.subtitle || o.text) : (o.text && o.subtitle ? o.subtitle : "");
|
|
658
|
+
// The drawn prose keeps its inline emphasis (`**three**` is bold on
|
|
659
|
+
// every renderer, as in the native reference); the descriptor parses it with
|
|
660
|
+
// `markdown: true`. Every `*Hidden` flag and the accessibility `label` follow
|
|
661
|
+
// the STRIPPED value: prose that is only markup (`---`, `***`, an image with
|
|
662
|
+
// empty alt) strips to "" and must not paint an empty node, and a screen
|
|
663
|
+
// reader must not read `**`.
|
|
664
|
+
const rowTitle = emphasisMarkdown(titleSrc);
|
|
665
|
+
const rowSubtitle = emphasisMarkdown(subtitleSrc);
|
|
666
|
+
const text = emphasisMarkdown(o.text);
|
|
667
|
+
const listText = emphasisMarkdown(o.listText);
|
|
662
668
|
const benefits = (o.benefits ?? []).filter((b) => b.text);
|
|
663
669
|
const badge = stripMarkdown(o.badge || "");
|
|
664
670
|
return {
|
|
665
671
|
id: `o${i}`,
|
|
666
672
|
value: o.value,
|
|
667
673
|
title: rowTitle,
|
|
674
|
+
label: drawnText(rowTitle),
|
|
668
675
|
subtitle: rowSubtitle, subtitleHidden: !rowSubtitle,
|
|
669
676
|
text, textHidden: !text,
|
|
670
677
|
pictureUrl, pictureHidden: !pictureUrl,
|
|
@@ -693,6 +700,20 @@ function isDisclosedSame(disclose: Disclose, url: string): boolean {
|
|
|
693
700
|
return disclose({ label: probe, url }) === probe;
|
|
694
701
|
}
|
|
695
702
|
|
|
703
|
+
/** A widget persisted by a bundle that predates `WidgetOptionRow.label` — rows carry
|
|
704
|
+
* plain titles and no label. Rehydrating one as saved would leave every row's
|
|
705
|
+
* accessibility name empty, so its label is backfilled from the title. */
|
|
706
|
+
export function withLabels(w: WidgetView): WidgetView {
|
|
707
|
+
const fill = (rows: WidgetOptionRow[] | undefined) =>
|
|
708
|
+
rows?.map((o) => (typeof o.label === "string" ? o : { ...o, label: drawnText(o.title) }));
|
|
709
|
+
return {
|
|
710
|
+
...w,
|
|
711
|
+
options: fill(w.options) ?? w.options,
|
|
712
|
+
suggestions: fill(w.suggestions) ?? w.suggestions,
|
|
713
|
+
questions: w.questions?.map((q) => ({ ...q, choices: fill(q.choices) ?? q.choices })) ?? w.questions,
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
|
|
696
717
|
/** Re-derive an ASYNC_TOOL widget for a new job state.
|
|
697
718
|
*
|
|
698
719
|
* Separate from `viewOf` because it runs on a LIVE widget rather than a fresh
|