• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jumpinjackie / mapguide-react-layout / 15558794793

10 Jun 2025 11:55AM UTC coverage: 34.772% (-0.001%) from 34.773%
15558794793

push

github

jumpinjackie
Update vitest

1323 of 1791 branches covered (73.87%)

7864 of 22616 relevant lines covered (34.77%)

8.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.89
/src/api/registry/command-spec.ts
1
import { ApplicationDefinition, ContainerItem, UIWidget, Widget } from '../contracts/fusion';
2
import { DefaultCommands, isSupportedCommandInStatelessMode } from './command';
1✔
3
import { DefaultComponentNames } from './component';
1✔
4
import { tr } from '../i18n';
1✔
5
import { CommandTarget, Dictionary, ICommand, IInvokeUrlCommand, ISearchCommand } from '../common';
6
import { assertNever } from '../../utils/never';
1✔
7
import { strIsNullOrEmpty } from '../../utils/string';
1✔
8
import { warn } from '../../utils/logger';
1✔
9
import { UIItem, CommandDef, isCommandItem, isTargetedCommand, isBasicCommand, isSeparatorItem, isFlyoutItem, WebLayout, isInvokeURLCommand, isSearchCommand } from '../contracts/weblayout';
1✔
10
import { isStateless } from '../../actions/init-command';
1✔
11
import { SPRITE_INVOKE_SCRIPT, SPRITE_INVOKE_URL } from '../../constants/assets';
1✔
12
import { WEBLAYOUT_CONTEXTMENU, WEBLAYOUT_TASKMENU } from '../../constants';
1✔
13
import { ScopedId } from '../../utils/scoped-id';
1✔
14

15
const scopedId = new ScopedId();
1✔
16

17
function isCommandSpec(cmd: ICommandSpec | IUnknownCommandSpec): cmd is ICommandSpec {
74✔
18
    return !strIsNullOrEmpty((cmd as any).command);
74✔
19
}
74✔
20

21
export function isUIWidget(widget: any): widget is UIWidget {
1✔
22
    return widget.WidgetType === "UiWidgetType";
237✔
23
}
237✔
24

25
/**
26
 *
27
 */
28
export interface ToolbarConf {
29
    items: (IFlyoutSpec | ISeparatorSpec | IUnknownCommandSpec | ICommandSpec)[];
30
}
31

32
/**
33
 *
34
 */
35
export interface PreparedSubMenuSet {
36
    toolbars: Dictionary<ToolbarConf>;
37
    flyouts: Dictionary<IFlyoutSpec>;
38
}
39

40
/**
41
 * @hidden
42
 */
43
export function isFlyoutSpec(item: any): item is IFlyoutSpec {
1✔
44
    return typeof (item.children) != 'undefined';
×
45
}
×
46

47
/**
48
 *
49
 */
50
export interface IFlyoutSpec {
51
    label?: string;
52
    tooltip?: string;
53
    icon?: string;
54
    spriteClass?: string;
55
    children: (IFlyoutSpec | ISeparatorSpec | IUnknownCommandSpec | ICommandSpec)[];
56
}
57

58
/**
59
 *
60
 */
61
export interface ISeparatorSpec {
62
    isSeparator: boolean;
63
}
64

65
/**
66
 *
67
 */
68
export interface IUnknownCommandSpec {
69
    error: string;
70
}
71

72
/**
73
 *
74
 */
75
export interface ICommandSpec {
76
    icon: string;
77
    spriteClass: string;
78
    label: string | null;
79
    tooltip: string;
80
    parameters: any;
81
    command?: string;
82
    componentName?: string;
83
    flyoutId?: string;
84
}
85

86
function makeCommand(widget: UIWidget, noToolbarLabels: boolean, cmdType: DefaultCommands): ICommandSpec {
169✔
87
    return { icon: widget.ImageUrl, spriteClass: widget.ImageClass, command: cmdType, label: (noToolbarLabels ? null : widget.Label), tooltip: widget.Tooltip, parameters: widget.Extension };
169!
88
}
169✔
89

90
function convertWidget(widget: UIWidget, locale: string, noToolbarLabels: boolean): ICommandSpec | IUnknownCommandSpec {
207✔
91
    switch (widget.Type) {
207✔
92
        case "Select":
207✔
93
            return makeCommand(widget, noToolbarLabels, DefaultCommands.Select);
12✔
94
        case "Pan":
207✔
95
            return makeCommand(widget, noToolbarLabels, DefaultCommands.Pan);
10✔
96
        //case "PanQuery":
97
        //case "PanOnClick":
98
        case "Zoom":
207✔
99
            return makeCommand(widget, noToolbarLabels, DefaultCommands.Zoom);
9✔
100
        case "ZoomOnClick": //Covers in and out. Look at Factor parameter
207✔
101
            {
19✔
102
                const factor = parseFloat(widget.Extension.Factor);
19✔
103
                if (factor >= 1.0) {
19✔
104
                    return makeCommand(widget, noToolbarLabels, DefaultCommands.ZoomIn);
9✔
105
                } else {
19✔
106
                    return makeCommand(widget, noToolbarLabels, DefaultCommands.ZoomOut);
10✔
107
                }
10✔
108
            }
19✔
109
        case "InitialMapView":
207✔
110
            return makeCommand(widget, noToolbarLabels, DefaultCommands.ZoomExtents);
6✔
111
        case "ZoomToSelection":
207✔
112
            return makeCommand(widget, noToolbarLabels, DefaultCommands.ZoomToSelection);
7✔
113
        case "ExtentHistory": //Covers prev and next. Look at Direction parameter
207✔
114
            {
12✔
115
                if (widget.Extension.Direction == "previous") {
12✔
116
                    return makeCommand(widget, noToolbarLabels, DefaultCommands.PreviousView);
4✔
117
                } else {
12✔
118
                    return makeCommand(widget, noToolbarLabels, DefaultCommands.NextView);
8✔
119
                }
8✔
120
            }
12✔
121
        case "CenterSelection":
207!
122
            return makeCommand(widget, noToolbarLabels, DefaultCommands.CenterSelection);
×
123
        case "About":
207✔
124
            return makeCommand(widget, noToolbarLabels, DefaultCommands.About);
4✔
125
        case "BufferPanel":
207✔
126
            return makeCommand(widget, noToolbarLabels, DefaultCommands.Buffer);
9✔
127
        case "ClearSelection":
207✔
128
            return makeCommand(widget, noToolbarLabels, DefaultCommands.ClearSelection);
6✔
129
        //case "ColorPicker":
130
        case "CoordinateTracker":
207✔
131
            return makeCommand(widget, noToolbarLabels, DefaultCommands.CoordinateTracker);
4✔
132
        case "FeatureInfo":
207✔
133
            return makeCommand(widget, noToolbarLabels, DefaultCommands.FeatureInfo);
6✔
134
        case "Geolocation":
207✔
135
            return makeCommand(widget, noToolbarLabels, DefaultCommands.Geolocation);
2✔
136
        //case "GoogleStreetViewer":
137
        case "Help":
207✔
138
            return makeCommand(widget, noToolbarLabels, DefaultCommands.Help);
4✔
139
        case "Maptip":
207✔
140
            return makeCommand(widget, noToolbarLabels, DefaultCommands.MapTip);
3✔
141
        case "MapMenu":
207✔
142
            return { icon: widget.ImageUrl, spriteClass: widget.ImageClass, label: (noToolbarLabels ? null : widget.Label), tooltip: widget.Tooltip, componentName: DefaultComponentNames.MapMenu, flyoutId: `${DefaultComponentNames.MapMenu}_${scopedId.next()}`, parameters: widget.Extension };
3!
143
        case "Query":
207✔
144
            return makeCommand(widget, noToolbarLabels, DefaultCommands.Query);
9✔
145
        case "QuickPlot":
207✔
146
            return makeCommand(widget, noToolbarLabels, DefaultCommands.QuickPlot);
3✔
147
        case "Redline":
207✔
148
            return makeCommand(widget, noToolbarLabels, DefaultCommands.Redline);
9✔
149
        case "RefreshMap":
207✔
150
            return makeCommand(widget, noToolbarLabels, DefaultCommands.RefreshMap);
4✔
151
        //case "SaveMap":
152
        case "InvokeURL": //Commands with this name would've been registered beforehand
207✔
153
        case "Search":
207✔
154
            return { icon: widget.ImageUrl, spriteClass: widget.ImageClass, command: widget.Name, label: (noToolbarLabels ? null : widget.Label), tooltip: widget.Tooltip, parameters: widget.Extension };
15!
155
        case "SelectPolygon":
207✔
156
            return makeCommand(widget, noToolbarLabels, DefaultCommands.SelectPolygon);
4✔
157
        case "SelectRadius":
207✔
158
            return makeCommand(widget, noToolbarLabels, DefaultCommands.SelectRadius);
4✔
159
        //case "SelectRadiusValue":
160
        case "SelectWithin":
207✔
161
            return makeCommand(widget, noToolbarLabels, DefaultCommands.SelectWithin);
1✔
162
        case "Theme":
207✔
163
            return makeCommand(widget, noToolbarLabels, DefaultCommands.Theme);
6✔
164
        case "ViewOptions":
207✔
165
            return makeCommand(widget, noToolbarLabels, DefaultCommands.ViewerOptions);
4✔
166
        case "Measure":
207✔
167
            return makeCommand(widget, noToolbarLabels, DefaultCommands.Measure);
10✔
168
        case "Print":
207✔
169
            return makeCommand(widget, noToolbarLabels, DefaultCommands.Print);
2✔
170
        case "BasemapSwitcher":
207✔
171
            return { icon: widget.ImageUrl, spriteClass: widget.ImageClass, label: (noToolbarLabels ? null : widget.Label), tooltip: widget.Tooltip, componentName: DefaultComponentNames.BaseMapSwitcher, flyoutId: `${DefaultComponentNames.BaseMapSwitcher}_${scopedId.next()}`, parameters: widget.Extension };
2!
172
        case "InvokeScript":
207✔
173
            return { icon: widget.ImageUrl, spriteClass: widget.ImageClass, command: widget.Name, label: (noToolbarLabels ? null : widget.Label), tooltip: widget.Tooltip, parameters: widget.Extension };
12!
174
        default:
207✔
175
            return { error: tr("UNKNOWN_WIDGET", locale, { widget: widget.Type }) }
6✔
176
    }
207✔
177
}
207✔
178

179
/**
180
 * @hidden
181
 * 
182
 * @param isStateless 
183
 * @param items 
184
 * @param widgetsByKey 
185
 * @param locale 
186
 * @param noToolbarLabels 
187
 * @returns 
188
 */
189
export function convertFlexLayoutUIItems(isStateless: boolean, items: ContainerItem[], widgetsByKey: Dictionary<Widget>, locale: string, noToolbarLabels = false): (IFlyoutSpec | ISeparatorSpec | IUnknownCommandSpec | ICommandSpec)[] {
1✔
190
    const converted = items.map(item => {
33✔
191
        switch (item.Function) {
256✔
192
            case "Widget":
256✔
193
                {
219✔
194
                    const widget = widgetsByKey[item.Widget];
219✔
195
                    if (widget && isUIWidget(widget)) {
219✔
196
                        const cmd = convertWidget(widget, locale, noToolbarLabels);
207✔
197
                        if (isStateless && isCommandSpec(cmd) && !isSupportedCommandInStatelessMode(cmd.command)) {
207✔
198
                            console.warn(`The widget (${widget.Name}) references a command (${cmd.command}) that is not supported in stateless mode. This widget will always be disabled`);
19✔
199
                        }
19✔
200
                        return cmd;
207✔
201
                    }
207✔
202
                }
219✔
203
            case "Separator":
256✔
204
                return { isSeparator: true } as ISeparatorSpec;
37✔
205
            case "Flyout":
256✔
206
                return {
12✔
207
                    label: item.Label,
12✔
208
                    tooltip: item.Tooltip,
12✔
209
                    icon: item.ImageUrl,
12✔
210
                    spriteClass: item.ImageClass,
12✔
211
                    children: convertFlexLayoutUIItems(isStateless, item.Item, widgetsByKey, locale)
12✔
212
                } as IFlyoutSpec;
12✔
213
            default:
256!
214
                assertNever(item);
×
215
        }
256!
216
        return null;
×
217
    })
33✔
218
        .filter(i => i != null)
33✔
219
        .map(i => i as (IFlyoutSpec | ISeparatorSpec | IUnknownCommandSpec | ICommandSpec));
33✔
220
    return converted;
33✔
221
}
33✔
222

223
function tryTranslateImageUrlToSpriteClass(imageUrl: string): string | undefined {
37✔
224
    switch (imageUrl) {
37✔
225
        case "../stdicons/icon_invokeurl.gif":
37✔
226
            return SPRITE_INVOKE_URL;
5✔
227
        case "../stdicons/icon_invokescript.gif":
37!
228
            return SPRITE_INVOKE_SCRIPT;
×
229
    }
37✔
230
}
37✔
231

232
/**
233
 * @hidden
234
 * 
235
 * @param items 
236
 * @param cmdsByKey 
237
 * @param locale 
238
 * @param noToolbarLabels 
239
 * @returns 
240
 */
241
export function convertWebLayoutUIItems(items: UIItem[] | undefined, cmdsByKey: Dictionary<CommandDef>, locale: string, noToolbarLabels = true): (IFlyoutSpec | ISeparatorSpec | IUnknownCommandSpec | ICommandSpec)[] {
1✔
242
    const converted = (items || []).map(item => {
6!
243
        if (isCommandItem(item)) {
58✔
244
            const cmdDef: CommandDef = cmdsByKey[item.Command];
43✔
245
            if (!cmdDef) {
43!
246
                warn(`Invalid reference to command: ${item.Command}`);
×
247
                return { error: tr("UNKNOWN_COMMAND_REFERENCE", locale, { command: item.Command }) } as IUnknownCommandSpec;
×
248
            } else if (cmdDef.TargetViewer != "Dwf") {
43✔
249
                let icon: Partial<Pick<ICommandSpec, "icon" | "spriteClass">> = {};
38✔
250
                if (cmdDef.ImageURL) {
38✔
251
                    icon.spriteClass = tryTranslateImageUrlToSpriteClass(cmdDef.ImageURL);
37✔
252
                    if (!icon.spriteClass) {
37✔
253
                        icon.icon = cmdDef.ImageURL;
32✔
254
                    }
32✔
255
                }
37✔
256
                const commonParams: any = {};
38✔
257
                if (isTargetedCommand(cmdDef)) {
38✔
258
                    commonParams.Target = cmdDef.Target;
15✔
259
                    commonParams.TargetFrame = cmdDef.TargetFrame;
15✔
260
                }
15✔
261
                if (isBasicCommand(cmdDef)) {
38✔
262
                    let action: string = cmdDef.Action;
23✔
263
                    if (action == "ZoomRectangle") {
23✔
264
                        action = DefaultCommands.Zoom;
2✔
265
                    } else if (action == "FitToWindow") {
23✔
266
                        action = DefaultCommands.ZoomExtents;
2✔
267
                    } else if (action == "Refresh") {
21✔
268
                        action = DefaultCommands.RefreshMap;
1✔
269
                    }
1✔
270
                    return { command: action, label: (noToolbarLabels ? null : cmdDef.Label), tooltip: cmdDef.Tooltip, parameters: commonParams, ...icon };
23✔
271
                } else {
38✔
272
                    switch (cmdDef["@xsi:type"]) {
15✔
273
                        case "ViewOptionsCommandType":
15✔
274
                            return { command: DefaultCommands.ViewerOptions, label: (noToolbarLabels ? null : cmdDef.Label), tooltip: cmdDef.Tooltip, parameters: commonParams };
1!
275
                        case "MeasureCommandType":
15✔
276
                            return { command: DefaultCommands.Measure, label: (noToolbarLabels ? null : cmdDef.Label), tooltip: cmdDef.Tooltip, parameters: commonParams };
3✔
277
                        case "HelpCommandType":
15✔
278
                            return { command: DefaultCommands.Help, label: (noToolbarLabels ? null : cmdDef.Label), tooltip: cmdDef.Tooltip, parameters: commonParams };
1!
279
                        case "BufferCommandType":
15✔
280
                            return { command: DefaultCommands.Buffer, label: (noToolbarLabels ? null : cmdDef.Label), tooltip: cmdDef.Tooltip, parameters: commonParams };
3✔
281
                        case "SelectWithinCommandType":
15✔
282
                            return { command: DefaultCommands.SelectWithin, label: (noToolbarLabels ? null : cmdDef.Label), tooltip: cmdDef.Tooltip, parameters: commonParams };
1!
283
                        case "GetPrintablePageCommandType":
15✔
284
                            return { command: DefaultCommands.QuickPlot, label: (noToolbarLabels ? null : cmdDef.Label), tooltip: cmdDef.Tooltip, parameters: commonParams };
1!
285
                        default:
15✔
286
                            return { command: cmdDef.Name, label: (noToolbarLabels ? null : cmdDef.Label), tooltip: cmdDef.Tooltip, parameters: commonParams, ...icon };
5!
287
                    }
15✔
288
                }
15✔
289
            }
38✔
290
        } else if (isSeparatorItem(item)) {
58✔
291
            return { isSeparator: true } as ISeparatorSpec;
12✔
292
        } else if (isFlyoutItem(item)) {
15✔
293
            return {
3✔
294
                label: item.Label,
3✔
295
                tooltip: item.Tooltip,
3✔
296
                children: convertWebLayoutUIItems(item.SubItem, cmdsByKey, locale, false)
3✔
297
            } as IFlyoutSpec;
3✔
298
        } else {
3!
299
            assertNever(item);
×
300
        }
✔
301
        return null;
5✔
302
    })
6✔
303
        .filter(i => i != null)
6✔
304
        .map(i => i as (IFlyoutSpec | ISeparatorSpec | IUnknownCommandSpec | ICommandSpec));
6✔
305
    return converted;
6✔
306
}
6✔
307

308
function convertToCommandTarget(fusionCmdTarget: string): CommandTarget {
18✔
309
    //Treat empty/undefined target as new window
310
    if (strIsNullOrEmpty(fusionCmdTarget)) {
18!
311
        return "NewWindow";
×
312
    }
×
313
    switch (fusionCmdTarget) {
18✔
314
        case "SearchWindow":
18!
315
        case "InvokeUrlWindow":
18✔
316
            return "NewWindow";
2✔
317
        case "TaskPane":
18✔
318
            return "TaskPane";
16✔
319
        default:
18!
320
            return "SpecifiedFrame";
×
321
    }
18✔
322
}
18✔
323
export type CommandRegistrationFunc = (name: string, cmdDef: ICommand | IInvokeUrlCommand | ISearchCommand) => void;
324

325
export function parseWidgetsInAppDef(appDef: ApplicationDefinition, cmdRegister: CommandRegistrationFunc) {
1✔
326
    let taskPane: Widget | undefined;
3✔
327
    let viewSize: Widget | undefined;
3✔
328
    let hasLegend = false;
3✔
329
    let hasStatus = false;
3✔
330
    let hasNavigator = false;
3✔
331
    let hasSelectionPanel = false;
3✔
332
    let hasTaskBar = false;
3✔
333
    let initialTask: string;
3✔
334
    const isStatelessAppDef = isStateless(appDef);
3✔
335
    const widgetsByKey: Dictionary<Widget> = {};
3✔
336
    //Register any InvokeURL and Search commands. Also set capabilities along the way
337
    for (const widgetSet of appDef.WidgetSet) {
3✔
338
        for (const widget of widgetSet.Widget) {
3✔
339
            const cmd = widget.Extension;
211✔
340
            switch (widget.Type) {
211✔
341
                case "TaskPane":
211✔
342
                    taskPane = widget;
3✔
343
                    break;
3✔
344
                case "ViewSize":
211✔
345
                    viewSize = widget;
3✔
346
                    break;
3✔
347
                case "Legend":
211✔
348
                    hasLegend = true;
3✔
349
                    break;
3✔
350
                case "SelectionPanel":
211✔
351
                    hasSelectionPanel = true;
3✔
352
                    break;
3✔
353
                case "CursorPosition":
211✔
354
                case "SelectionInfo":
211✔
355
                    hasStatus = true;
6✔
356
                    break;
6✔
357
                case "Navigator":
211✔
358
                    hasNavigator = true;
3✔
359
                    break;
3✔
360
                case "Search":
211✔
361
                    cmdRegister(widget.Name, {
8✔
362
                        layer: cmd.Layer,
8✔
363
                        prompt: cmd.Prompt,
8✔
364
                        resultColumns: cmd.ResultColumns,
8✔
365
                        filter: cmd.Filter,
8✔
366
                        matchLimit: cmd.MatchLimit,
8✔
367
                        title: (cmd.Title || (isUIWidget(widget) ? widget.Label : undefined)),
8!
368
                        target: convertToCommandTarget(cmd.Target),
8✔
369
                        targetFrame: cmd.Target
8✔
370
                    });
8✔
371
                    if (isStatelessAppDef) {
8!
372
                        console.warn(`The search command (${widget.Name}) is not supported in stateless mode. This widget will always be disabled`);
×
373
                    }
×
374
                    break;
8✔
375
                case "InvokeURL":
211✔
376
                    cmdRegister(widget.Name, {
10✔
377
                        url: cmd.Url,
10✔
378
                        disableIfSelectionEmpty: cmd.DisableIfSelectionEmpty,
10✔
379
                        target: convertToCommandTarget(cmd.Target),
10✔
380
                        targetFrame: cmd.Target,
10✔
381
                        parameters: (cmd.AdditionalParameter || []).map((p: any) => {
10✔
382
                            return { name: p.Key, value: p.Value };
×
383
                        }),
10✔
384
                        title: isUIWidget(widget) ? widget.Label : undefined
10!
385
                    });/*
10✔
386
                        if (config.isStateless && !strStartsWith(cmd.Url, "component://")) {
387
                            console.warn(`The InvokeURL command (${widget.Name}) is not supported in stateless mode. This widget will always be disabled`);
388
                        }*/
389
                    break;
10✔
390
            }
211✔
391
            widgetsByKey[widget.Name] = widget;
211✔
392
        }
211✔
393
    }
3✔
394

395
    if (taskPane) {
3✔
396
        hasTaskBar = true; //Fusion flex layouts can't control the visiblity of this
3✔
397
        initialTask = taskPane.Extension.InitialTask || "server/TaskPane.html";
3✔
398
    } else {
3!
399
        initialTask = "server/TaskPane.html";
×
400
    }
×
401

402
    return {
3✔
403
        taskPane,
3✔
404
        viewSize,
3✔
405
        initialTask,
3✔
406
        hasLegend,
3✔
407
        hasStatus,
3✔
408
        hasNavigator,
3✔
409
        hasSelectionPanel,
3✔
410
        hasTaskBar,
3✔
411
        isStateless: isStatelessAppDef,
3✔
412
        widgetsByKey
3✔
413
    };
3✔
414
}
3✔
415

416
export function parseCommandsInWebLayout(webLayout: WebLayout, cmdRegister: CommandRegistrationFunc) {
1✔
417
    const cmdsByKey: Dictionary<CommandDef> = {};
1✔
418
    //Register any InvokeURL and Search commands
419
    for (const cmd of webLayout.CommandSet.Command) {
1✔
420
        if (isInvokeURLCommand(cmd)) {
33✔
421
            cmdRegister(cmd.Name, {
5✔
422
                url: cmd.URL,
5✔
423
                disableIfSelectionEmpty: cmd.DisableIfSelectionEmpty,
5✔
424
                target: cmd.Target,
5✔
425
                targetFrame: cmd.TargetFrame,
5✔
426
                parameters: (cmd.AdditionalParameter || []).map(p => {
5!
427
                    return { name: p.Key, value: p.Value };
×
428
                }),
5✔
429
                title: cmd.Label
5✔
430
            });
5✔
431
        } else if (isSearchCommand(cmd)) {
33!
432
            cmdRegister(cmd.Name, {
×
433
                layer: cmd.Layer,
×
434
                prompt: cmd.Prompt,
×
435
                target: cmd.Target,
×
436
                targetFrame: cmd.TargetFrame,
×
437
                resultColumns: cmd.ResultColumns,
×
438
                filter: cmd.Filter,
×
439
                matchLimit: cmd.MatchLimit,
×
440
                title: cmd.Label
×
441
            });
×
442
        }
×
443
        cmdsByKey[cmd.Name] = cmd;
33✔
444
    }
33✔
445
    return cmdsByKey;
1✔
446
}
1✔
447

448
/**
449
 * @hidden
450
 * 
451
 * @param tbConf 
452
 * @returns 
453
 */
454
export function prepareSubMenus(tbConf: Dictionary<ToolbarConf>): [PreparedSubMenuSet, boolean] {
1✔
455
    const prepared: PreparedSubMenuSet = {
×
456
        toolbars: {},
×
457
        flyouts: {}
×
458
    };
×
459
    let bFoundContextMenu = false;
×
460
    for (const key in tbConf) {
×
461
        if (key == WEBLAYOUT_CONTEXTMENU) {
×
462
            bFoundContextMenu = true;
×
463
        }
×
464

465
        //Special cases: Task pane and Context Menu. Transfer all to flyout
466
        if (key == WEBLAYOUT_TASKMENU || key == WEBLAYOUT_CONTEXTMENU) {
×
467
            const flyoutId = key;
×
468
            prepared.flyouts[flyoutId] = {
×
469
                children: tbConf[key].items
×
470
            }
×
471
        } else {
×
472
            prepared.toolbars[key] = {
×
473
                items: []
×
474
            };
×
475
            for (const item of tbConf[key].items) {
×
476
                //Special case: contextmenu is all inline
477
                if (isFlyoutSpec(item) && key != WEBLAYOUT_CONTEXTMENU) {
×
478
                    const flyoutId = `${item.label}_${scopedId.next()}`;
×
479
                    prepared.toolbars[key].items.push({
×
480
                        label: item.label,
×
481
                        tooltip: item.tooltip,
×
482
                        icon: item.icon,
×
483
                        spriteClass: item.spriteClass,
×
484
                        flyoutId: flyoutId
×
485
                    } as ICommandSpec);
×
486
                    prepared.flyouts[flyoutId] = {
×
487
                        children: item.children
×
488
                    }
×
489
                } else {
×
490
                    prepared.toolbars[key].items.push(item);
×
491
                }
×
492
            }
×
493
        }
×
494
    }
×
495
    return [prepared, bFoundContextMenu]
×
496
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc