@vonage/vivid 5.20.0 → 5.20.1

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.
@@ -6017,6 +6017,9 @@ var $s = Qs(!1, !0), ec = Qs(!0, !0), tc = (e) => typeof e == "function", nc = (
6017
6017
  updateBindings() {
6018
6018
  for (let e of this.bindings) e();
6019
6019
  }
6020
+ shouldReturnFocusToEditor() {
6021
+ return this.evalProp(this.props.shouldReturnFocusToEditor);
6022
+ }
6020
6023
  bindToEl(e, t = {}, n = [], r = []) {
6021
6024
  for (let n in t) this.bindProp(t[n], (t) => {
6022
6025
  e[n] = t;
@@ -6066,7 +6069,7 @@ var $s = Qs(!1, !0), ec = Qs(!0, !0), tc = (e) => typeof e == "function", nc = (
6066
6069
  pressed: () => !!e.evalProp(t.active),
6067
6070
  ariaPressed: t.active === void 0 ? void 0 : () => e.evalProp(t.active) ? "true" : "false"
6068
6071
  }, [nc("click", t.onClick, (t) => () => {
6069
- t() || e.view.focus();
6072
+ !t() && e.shouldReturnFocusToEditor() && e.view.focus();
6070
6073
  })]), sc(e, {
6071
6074
  enabled: () => !!(e.evalProp(t.icon) && !e.evalProp(t.noTooltip) && !c()),
6072
6075
  label: t.label,
@@ -6094,7 +6097,7 @@ var $s = Qs(!1, !0), ec = Qs(!0, !0), tc = (e) => typeof e == "function", nc = (
6094
6097
  controlType: "radio",
6095
6098
  checkedAppearance: "tick-only"
6096
6099
  }, [nc("change", t.onSelect, (n) => () => {
6097
- r.checked && !r.disabled && e.evalProp(t.checked) !== r.checked && (n(), e.view.focus());
6100
+ r.checked && !r.disabled && e.evalProp(t.checked) !== r.checked && (n(), e.shouldReturnFocusToEditor() && e.view.focus());
6098
6101
  })]), r;
6099
6102
  }, uc = (e, t) => ic(e, {
6100
6103
  slot: t.slot,
@@ -6129,7 +6132,7 @@ var fc = (e, t) => K(e, {
6129
6132
  disabled: n
6130
6133
  }, [nc("change", t.onSelect, (t) => () => {
6131
6134
  let n = r.value;
6132
- n && (t(n), e.view.focus());
6135
+ n && (t(n), e.shouldReturnFocusToEditor() && e.view.focus());
6133
6136
  })], t.children), queueMicrotask(() => {
6134
6137
  e.bindProp(t.value, (e) => r.value = e);
6135
6138
  });
@@ -6180,7 +6183,7 @@ var fc = (e, t) => K(e, {
6180
6183
  for (let [r, i] of Object.entries(t.assignedProps)) n[r] = e.evalProp(i);
6181
6184
  for (let [r, a] of Object.entries(t.assignedEvents)) {
6182
6185
  let t = (t) => {
6183
- a(t), e.view.focus();
6186
+ a(t), e.shouldReturnFocusToEditor() && e.view.focus();
6184
6187
  };
6185
6188
  n.addEventListener(r, t), i.push({
6186
6189
  el: n,
@@ -7531,26 +7534,33 @@ var ou = (e) => e.parent.textBetween(0, e.parentOffset, void 0, ""), su = cla
7531
7534
  for (let t of _e(e.features.flatMap((t) => t.getToolbarItems(e)))) n.get(t.section).push(t);
7532
7535
  let r = e.getFeature("RteCore");
7533
7536
  return [this.contribution(this.hidden.plugin), this.contribution(new N({ view: (i) => {
7534
- let a = new rc(i, e, {
7537
+ let a = !1, o = new rc(i, e, {
7535
7538
  popupPlacement: this.config?.popupDirection === "outward" ? "bottom" : "top",
7536
7539
  menuOffset: 8,
7537
- disabled: () => r.disabled.getValue(e)
7538
- }), o = i.dom.getRootNode().querySelector(".toolbar");
7539
- a.bindProp(() => this.hidden.getValue(e), (e) => {
7540
- o.classList.toggle("toolbar--hidden", e);
7540
+ disabled: () => r.disabled.getValue(e),
7541
+ shouldReturnFocusToEditor: () => a
7542
+ }), s = i.dom.getRootNode().querySelector(".toolbar"), c = -Infinity, l = () => {
7543
+ i.hasFocus() && (a = !0), c = Date.now();
7544
+ }, u = () => {
7545
+ Date.now() - c > 250 && (a = !1);
7546
+ }, d = (e) => {
7547
+ s.contains(e.relatedTarget) || (a = !1);
7548
+ };
7549
+ s.addEventListener("mousedown", l, { capture: !0 }), s.addEventListener("focusin", u), s.addEventListener("focusout", d), o.bindProp(() => this.hidden.getValue(e), (e) => {
7550
+ s.classList.toggle("toolbar--hidden", e);
7541
7551
  });
7542
- let s = !1;
7552
+ let f = !1;
7543
7553
  for (let e of t) {
7544
7554
  let t = n.get(e);
7545
- t.length && s && (o.appendChild(hc(a)), s = !1);
7546
- for (let e of t) o.appendChild(e.render(a)), s = !0;
7555
+ t.length && f && (s.appendChild(hc(o)), f = !1);
7556
+ for (let e of t) s.appendChild(e.render(o)), f = !0;
7547
7557
  }
7548
7558
  return {
7549
7559
  update() {
7550
- a.updateBindings();
7560
+ o.updateBindings();
7551
7561
  },
7552
7562
  destroy() {
7553
- o.innerHTML = "";
7563
+ s.innerHTML = "", s.removeEventListener("mousedown", l, { capture: !0 }), s.removeEventListener("focusin", u), s.removeEventListener("focusout", d), a = !1;
7554
7564
  }
7555
7565
  };
7556
7566
  } }))];
@@ -8465,7 +8475,10 @@ var fd = y(class extends w {
8465
8475
  return null;
8466
8476
  } },
8467
8477
  view: (t) => {
8468
- let r = new rc(t, e, { popupPlacement: "bottom" });
8478
+ let r = new rc(t, e, {
8479
+ popupPlacement: "bottom",
8480
+ shouldReturnFocusToEditor: !0
8481
+ });
8469
8482
  n = e.createComponent(E), n.anchorId = "current-link";
8470
8483
  let i = ic(r, {
8471
8484
  className: "link-popover",
@@ -8571,7 +8584,7 @@ var fd = y(class extends w {
8571
8584
  },
8572
8585
  onClick: () => {
8573
8586
  let { state: t, dispatch: n } = r.view;
8574
- this.insertLink(e, a.value, i.value)(t, n);
8587
+ this.insertLink(e, a.value, i.value)(t, n), this.toolbarMenu.open = !1;
8575
8588
  }
8576
8589
  }), s = () => {
8577
8590
  o.querySelector("[data-vvd-component=\"button\"]").disabled = !(i.value.length && n(a.value));
@@ -8744,7 +8757,10 @@ var fd = y(class extends w {
8744
8757
  return [this.contribution(new N({
8745
8758
  props: { nodeViews: { inlineImage: (e, t, n) => new _d(e, t, n, this.config) } },
8746
8759
  view: (n) => {
8747
- let r = new rc(n, e, { popupPlacement: "bottom" });
8760
+ let r = new rc(n, e, {
8761
+ popupPlacement: "bottom",
8762
+ shouldReturnFocusToEditor: !0
8763
+ });
8748
8764
  t = e.createComponent(E), t.offset = 4;
8749
8765
  let i = ic(r, {
8750
8766
  className: "inline-image-popover",
@@ -9167,7 +9183,10 @@ var Nd = (e, t, n) => {
9167
9183
  return t ? t.loadingDecoration.add(e.doc, [ja.inline(t.match.start, t.match.end, { id: `suggest-anchor-${this.featureId}` })]) : null;
9168
9184
  } },
9169
9185
  view: (t) => {
9170
- let n = new rc(t, e, { popupPlacement: "bottom" }), r = e.createComponent(E);
9186
+ let n = new rc(t, e, {
9187
+ popupPlacement: "bottom",
9188
+ shouldReturnFocusToEditor: !0
9189
+ }), r = e.createComponent(E);
9171
9190
  r.anchorId = `suggest-anchor-${this.featureId}`, r.kind = "autocomplete", r.offset = 4;
9172
9191
  let i = ic(n, {
9173
9192
  className: "suggest-popover",
@@ -268,6 +268,9 @@ var UiCtx = class {
268
268
  updateBindings() {
269
269
  for (const binding of this.bindings) binding();
270
270
  }
271
+ shouldReturnFocusToEditor() {
272
+ return this.evalProp(this.props.shouldReturnFocusToEditor);
273
+ }
271
274
  bindToEl(target, props = {}, events = [], children = []) {
272
275
  for (const name in props) this.bindProp(props[name], (value) => {
273
276
  target[name] = value;
@@ -335,7 +338,7 @@ var createButton = (ctx, props) => {
335
338
  pressed: () => Boolean(ctx.evalProp(props.active)),
336
339
  ariaPressed: props.active !== void 0 ? () => ctx.evalProp(props.active) ? "true" : "false" : void 0
337
340
  }, [on("click", props.onClick, (onClick) => () => {
338
- if (!onClick()) ctx.view.focus();
341
+ if (!onClick() && ctx.shouldReturnFocusToEditor()) ctx.view.focus();
339
342
  })]);
340
343
  return createOptionalTooltip(ctx, {
341
344
  enabled: () => Boolean(ctx.evalProp(props.icon) && !ctx.evalProp(props.noTooltip) && !disabled()),
@@ -372,7 +375,7 @@ var createMenuItem = (ctx, props) => {
372
375
  if (item.checked && !item.disabled) {
373
376
  if (ctx.evalProp(props.checked) !== item.checked) {
374
377
  onSelect();
375
- ctx.view.focus();
378
+ if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
376
379
  }
377
380
  }
378
381
  })]);
@@ -420,7 +423,7 @@ var createSelect = (ctx, props) => {
420
423
  const value = select.value;
421
424
  if (value) {
422
425
  onSelect(value);
423
- ctx.view.focus();
426
+ if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
424
427
  }
425
428
  })], props.children);
426
429
  queueMicrotask(() => {
@@ -487,7 +490,7 @@ var createSingleSlot = (ctx, props) => {
487
490
  for (const [type, handler] of Object.entries(props.assignedEvents)) {
488
491
  const listener = (e) => {
489
492
  handler(e);
490
- ctx.view.focus();
493
+ if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
491
494
  };
492
495
  el.addEventListener(type, listener);
493
496
  listeners.push({
@@ -1423,12 +1426,28 @@ var RteToolbarFeatureImpl = class extends require_slottable_request.RteFeatureIm
1423
1426
  for (const toolbarItem of require_slottable_request.sortedContributions(rte.features.flatMap((f) => f.getToolbarItems(rte)))) itemsBySection.get(toolbarItem.section).push(toolbarItem);
1424
1427
  const core = rte.getFeature("RteCore");
1425
1428
  return [this.contribution(this.hidden.plugin), this.contribution(new prosemirror_state.Plugin({ view: (view) => {
1429
+ let focusCameFromEditorWithMouse = false;
1426
1430
  const ctx = new UiCtx(view, rte, {
1427
1431
  popupPlacement: this.config?.popupDirection === "outward" ? "bottom" : "top",
1428
1432
  menuOffset: 8,
1429
- disabled: () => core.disabled.getValue(rte)
1433
+ disabled: () => core.disabled.getValue(rte),
1434
+ shouldReturnFocusToEditor: () => focusCameFromEditorWithMouse
1430
1435
  });
1431
1436
  const toolbar = view.dom.getRootNode().querySelector(".toolbar");
1437
+ let mouseDownTime = -Infinity;
1438
+ const onMouseDown = () => {
1439
+ if (view.hasFocus()) focusCameFromEditorWithMouse = true;
1440
+ mouseDownTime = Date.now();
1441
+ };
1442
+ const onFocusIn = () => {
1443
+ if (Date.now() - mouseDownTime > 250) focusCameFromEditorWithMouse = false;
1444
+ };
1445
+ const onFocusOut = (e) => {
1446
+ if (!toolbar.contains(e.relatedTarget)) focusCameFromEditorWithMouse = false;
1447
+ };
1448
+ toolbar.addEventListener("mousedown", onMouseDown, { capture: true });
1449
+ toolbar.addEventListener("focusin", onFocusIn);
1450
+ toolbar.addEventListener("focusout", onFocusOut);
1432
1451
  ctx.bindProp(() => this.hidden.getValue(rte), (hidden) => {
1433
1452
  toolbar.classList.toggle("toolbar--hidden", hidden);
1434
1453
  });
@@ -1450,6 +1469,10 @@ var RteToolbarFeatureImpl = class extends require_slottable_request.RteFeatureIm
1450
1469
  },
1451
1470
  destroy() {
1452
1471
  toolbar.innerHTML = "";
1472
+ toolbar.removeEventListener("mousedown", onMouseDown, { capture: true });
1473
+ toolbar.removeEventListener("focusin", onFocusIn);
1474
+ toolbar.removeEventListener("focusout", onFocusOut);
1475
+ focusCameFromEditorWithMouse = false;
1453
1476
  }
1454
1477
  };
1455
1478
  } }))];
@@ -2402,7 +2425,10 @@ var RteLinkFeatureImpl = class extends require_slottable_request.RteFeatureImpl
2402
2425
  return null;
2403
2426
  } },
2404
2427
  view: (view) => {
2405
- const ctx = new UiCtx(view, rte, { popupPlacement: "bottom" });
2428
+ const ctx = new UiCtx(view, rte, {
2429
+ popupPlacement: "bottom",
2430
+ shouldReturnFocusToEditor: true
2431
+ });
2406
2432
  popup = rte.createComponent(Popover);
2407
2433
  popup.anchorId = "current-link";
2408
2434
  const content = createDiv(ctx, {
@@ -2527,6 +2553,7 @@ var RteLinkFeatureImpl = class extends require_slottable_request.RteFeatureImpl
2527
2553
  onClick: () => {
2528
2554
  const { state, dispatch } = ctx.view;
2529
2555
  this.insertLink(rte, urlField.value, textField.value)(state, dispatch);
2556
+ this.toolbarMenu.open = false;
2530
2557
  }
2531
2558
  });
2532
2559
  const updateValidation = () => {
@@ -2777,7 +2804,10 @@ var RteInlineImageFeatureImpl = class extends require_slottable_request.RteFeatu
2777
2804
  return [this.contribution(new prosemirror_state.Plugin({
2778
2805
  props: { nodeViews: { inlineImage: (node, view, getPos) => new InlineImageView(node, view, getPos, this.config) } },
2779
2806
  view: (view) => {
2780
- const ctx = new UiCtx(view, rte, { popupPlacement: "bottom" });
2807
+ const ctx = new UiCtx(view, rte, {
2808
+ popupPlacement: "bottom",
2809
+ shouldReturnFocusToEditor: true
2810
+ });
2781
2811
  popover = rte.createComponent(Popover);
2782
2812
  popover.offset = 4;
2783
2813
  const content = createDiv(ctx, {
@@ -3358,7 +3388,10 @@ var RteSuggestFeatureImpl = class extends require_slottable_request.RteFeatureIm
3358
3388
  return suggestState.loadingDecoration.add(state.doc, [prosemirror_view.Decoration.inline(suggestState.match.start, suggestState.match.end, { id: `suggest-anchor-${this.featureId}` })]);
3359
3389
  } },
3360
3390
  view: (view) => {
3361
- const ctx = new UiCtx(view, rte, { popupPlacement: "bottom" });
3391
+ const ctx = new UiCtx(view, rte, {
3392
+ popupPlacement: "bottom",
3393
+ shouldReturnFocusToEditor: true
3394
+ });
3362
3395
  const popover = rte.createComponent(Popover);
3363
3396
  popover.anchorId = `suggest-anchor-${this.featureId}`;
3364
3397
  popover.kind = "autocomplete";
@@ -266,6 +266,9 @@ var UiCtx = class {
266
266
  updateBindings() {
267
267
  for (const binding of this.bindings) binding();
268
268
  }
269
+ shouldReturnFocusToEditor() {
270
+ return this.evalProp(this.props.shouldReturnFocusToEditor);
271
+ }
269
272
  bindToEl(target, props = {}, events = [], children = []) {
270
273
  for (const name in props) this.bindProp(props[name], (value) => {
271
274
  target[name] = value;
@@ -333,7 +336,7 @@ var createButton = (ctx, props) => {
333
336
  pressed: () => Boolean(ctx.evalProp(props.active)),
334
337
  ariaPressed: props.active !== void 0 ? () => ctx.evalProp(props.active) ? "true" : "false" : void 0
335
338
  }, [on("click", props.onClick, (onClick) => () => {
336
- if (!onClick()) ctx.view.focus();
339
+ if (!onClick() && ctx.shouldReturnFocusToEditor()) ctx.view.focus();
337
340
  })]);
338
341
  return createOptionalTooltip(ctx, {
339
342
  enabled: () => Boolean(ctx.evalProp(props.icon) && !ctx.evalProp(props.noTooltip) && !disabled()),
@@ -370,7 +373,7 @@ var createMenuItem = (ctx, props) => {
370
373
  if (item.checked && !item.disabled) {
371
374
  if (ctx.evalProp(props.checked) !== item.checked) {
372
375
  onSelect();
373
- ctx.view.focus();
376
+ if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
374
377
  }
375
378
  }
376
379
  })]);
@@ -418,7 +421,7 @@ var createSelect = (ctx, props) => {
418
421
  const value = select.value;
419
422
  if (value) {
420
423
  onSelect(value);
421
- ctx.view.focus();
424
+ if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
422
425
  }
423
426
  })], props.children);
424
427
  queueMicrotask(() => {
@@ -485,7 +488,7 @@ var createSingleSlot = (ctx, props) => {
485
488
  for (const [type, handler] of Object.entries(props.assignedEvents)) {
486
489
  const listener = (e) => {
487
490
  handler(e);
488
- ctx.view.focus();
491
+ if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
489
492
  };
490
493
  el.addEventListener(type, listener);
491
494
  listeners.push({
@@ -1421,12 +1424,28 @@ var RteToolbarFeatureImpl = class extends RteFeatureImpl {
1421
1424
  for (const toolbarItem of sortedContributions(rte.features.flatMap((f) => f.getToolbarItems(rte)))) itemsBySection.get(toolbarItem.section).push(toolbarItem);
1422
1425
  const core = rte.getFeature("RteCore");
1423
1426
  return [this.contribution(this.hidden.plugin), this.contribution(new Plugin({ view: (view) => {
1427
+ let focusCameFromEditorWithMouse = false;
1424
1428
  const ctx = new UiCtx(view, rte, {
1425
1429
  popupPlacement: this.config?.popupDirection === "outward" ? "bottom" : "top",
1426
1430
  menuOffset: 8,
1427
- disabled: () => core.disabled.getValue(rte)
1431
+ disabled: () => core.disabled.getValue(rte),
1432
+ shouldReturnFocusToEditor: () => focusCameFromEditorWithMouse
1428
1433
  });
1429
1434
  const toolbar = view.dom.getRootNode().querySelector(".toolbar");
1435
+ let mouseDownTime = -Infinity;
1436
+ const onMouseDown = () => {
1437
+ if (view.hasFocus()) focusCameFromEditorWithMouse = true;
1438
+ mouseDownTime = Date.now();
1439
+ };
1440
+ const onFocusIn = () => {
1441
+ if (Date.now() - mouseDownTime > 250) focusCameFromEditorWithMouse = false;
1442
+ };
1443
+ const onFocusOut = (e) => {
1444
+ if (!toolbar.contains(e.relatedTarget)) focusCameFromEditorWithMouse = false;
1445
+ };
1446
+ toolbar.addEventListener("mousedown", onMouseDown, { capture: true });
1447
+ toolbar.addEventListener("focusin", onFocusIn);
1448
+ toolbar.addEventListener("focusout", onFocusOut);
1430
1449
  ctx.bindProp(() => this.hidden.getValue(rte), (hidden) => {
1431
1450
  toolbar.classList.toggle("toolbar--hidden", hidden);
1432
1451
  });
@@ -1448,6 +1467,10 @@ var RteToolbarFeatureImpl = class extends RteFeatureImpl {
1448
1467
  },
1449
1468
  destroy() {
1450
1469
  toolbar.innerHTML = "";
1470
+ toolbar.removeEventListener("mousedown", onMouseDown, { capture: true });
1471
+ toolbar.removeEventListener("focusin", onFocusIn);
1472
+ toolbar.removeEventListener("focusout", onFocusOut);
1473
+ focusCameFromEditorWithMouse = false;
1451
1474
  }
1452
1475
  };
1453
1476
  } }))];
@@ -2400,7 +2423,10 @@ var RteLinkFeatureImpl = class extends RteFeatureImpl {
2400
2423
  return null;
2401
2424
  } },
2402
2425
  view: (view) => {
2403
- const ctx = new UiCtx(view, rte, { popupPlacement: "bottom" });
2426
+ const ctx = new UiCtx(view, rte, {
2427
+ popupPlacement: "bottom",
2428
+ shouldReturnFocusToEditor: true
2429
+ });
2404
2430
  popup = rte.createComponent(Popover);
2405
2431
  popup.anchorId = "current-link";
2406
2432
  const content = createDiv(ctx, {
@@ -2525,6 +2551,7 @@ var RteLinkFeatureImpl = class extends RteFeatureImpl {
2525
2551
  onClick: () => {
2526
2552
  const { state, dispatch } = ctx.view;
2527
2553
  this.insertLink(rte, urlField.value, textField.value)(state, dispatch);
2554
+ this.toolbarMenu.open = false;
2528
2555
  }
2529
2556
  });
2530
2557
  const updateValidation = () => {
@@ -2775,7 +2802,10 @@ var RteInlineImageFeatureImpl = class extends RteFeatureImpl {
2775
2802
  return [this.contribution(new Plugin({
2776
2803
  props: { nodeViews: { inlineImage: (node, view, getPos) => new InlineImageView(node, view, getPos, this.config) } },
2777
2804
  view: (view) => {
2778
- const ctx = new UiCtx(view, rte, { popupPlacement: "bottom" });
2805
+ const ctx = new UiCtx(view, rte, {
2806
+ popupPlacement: "bottom",
2807
+ shouldReturnFocusToEditor: true
2808
+ });
2779
2809
  popover = rte.createComponent(Popover);
2780
2810
  popover.offset = 4;
2781
2811
  const content = createDiv(ctx, {
@@ -3356,7 +3386,10 @@ var RteSuggestFeatureImpl = class extends RteFeatureImpl {
3356
3386
  return suggestState.loadingDecoration.add(state.doc, [Decoration.inline(suggestState.match.start, suggestState.match.end, { id: `suggest-anchor-${this.featureId}` })]);
3357
3387
  } },
3358
3388
  view: (view) => {
3359
- const ctx = new UiCtx(view, rte, { popupPlacement: "bottom" });
3389
+ const ctx = new UiCtx(view, rte, {
3390
+ popupPlacement: "bottom",
3391
+ shouldReturnFocusToEditor: true
3392
+ });
3360
3393
  const popover = rte.createComponent(Popover);
3361
3394
  popover.anchorId = `suggest-anchor-${this.featureId}`;
3362
3395
  popover.kind = "autocomplete";
@@ -299,7 +299,7 @@ var ReplacedPropHandling = (Base) => {
299
299
  */
300
300
  var VividElement = class extends AriaMixin(ReplacedPropHandling(ReactiveControllerHostSupport(_microsoft_fast_element.FASTElement))) {
301
301
  static {
302
- this.VIVID_VERSION = "5.20.0";
302
+ this.VIVID_VERSION = "5.20.1";
303
303
  }
304
304
  /**
305
305
  * Add data-vvd-component attribute with component name globally,
@@ -298,7 +298,7 @@ var ReplacedPropHandling = (Base) => {
298
298
  */
299
299
  var VividElement = class extends AriaMixin(ReplacedPropHandling(ReactiveControllerHostSupport(FASTElement))) {
300
300
  static {
301
- this.VIVID_VERSION = "5.20.0";
301
+ this.VIVID_VERSION = "5.20.1";
302
302
  }
303
303
  /**
304
304
  * Add data-vvd-component attribute with component name globally,