@gitlab/ui 49.0.1 → 49.0.2

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.
Files changed (127) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/components/base/accordion/accordion.js +2 -8
  3. package/dist/components/base/accordion/accordion_item.js +0 -14
  4. package/dist/components/base/alert/alert.js +4 -22
  5. package/dist/components/base/avatar/avatar.js +0 -7
  6. package/dist/components/base/avatar_labeled/avatar_labeled.js +0 -2
  7. package/dist/components/base/avatars_inline/avatars_inline.js +2 -10
  8. package/dist/components/base/badge/badge.js +0 -8
  9. package/dist/components/base/banner/banner.js +0 -10
  10. package/dist/components/base/breadcrumb/breadcrumb.js +0 -12
  11. package/dist/components/base/breadcrumb/breadcrumb_item.js +0 -2
  12. package/dist/components/base/broadcast_message/broadcast_message.js +0 -3
  13. package/dist/components/base/button/button.js +0 -11
  14. package/dist/components/base/card/card.js +1 -2
  15. package/dist/components/base/datepicker/datepicker.js +7 -42
  16. package/dist/components/base/daterange_picker/daterange_picker.js +0 -23
  17. package/dist/components/base/drawer/drawer.js +0 -13
  18. package/dist/components/base/dropdown/dropdown.js +3 -17
  19. package/dist/components/base/dropdown/dropdown_item.js +2 -8
  20. package/dist/components/base/filtered_search/common_story_options.js +1 -2
  21. package/dist/components/base/filtered_search/filtered_search.js +9 -61
  22. package/dist/components/base/filtered_search/filtered_search_suggestion.js +0 -6
  23. package/dist/components/base/filtered_search/filtered_search_suggestion_list.js +0 -16
  24. package/dist/components/base/filtered_search/filtered_search_term.js +0 -9
  25. package/dist/components/base/filtered_search/filtered_search_token.js +10 -49
  26. package/dist/components/base/filtered_search/filtered_search_token_segment.js +3 -56
  27. package/dist/components/base/filtered_search/filtered_search_utils.js +7 -24
  28. package/dist/components/base/form/form_checkbox/form_checkbox.js +0 -2
  29. package/dist/components/base/form/form_checkbox_tree/checkbox_tree_node.js +0 -4
  30. package/dist/components/base/form/form_checkbox_tree/form_checkbox_tree.js +0 -10
  31. package/dist/components/base/form/form_checkbox_tree/models/node.js +1 -10
  32. package/dist/components/base/form/form_checkbox_tree/models/tree.js +16 -37
  33. package/dist/components/base/form/form_combobox/form_combobox.js +2 -36
  34. package/dist/components/base/form/form_group/form_group.js +2 -7
  35. package/dist/components/base/form/form_input/form_input.js +2 -8
  36. package/dist/components/base/form/form_input_group/form_input_group.js +0 -5
  37. package/dist/components/base/form/form_input_group/form_input_group_mixin.js +0 -8
  38. package/dist/components/base/form/form_radio_group/form_radio_group.js +0 -2
  39. package/dist/components/base/form/form_select/form_select.js +0 -3
  40. package/dist/components/base/form/form_textarea/form_textarea.js +2 -7
  41. package/dist/components/base/icon/icon.js +4 -14
  42. package/dist/components/base/infinite_scroll/infinite_scroll.js +7 -21
  43. package/dist/components/base/keyset_pagination/keyset_pagination.js +0 -9
  44. package/dist/components/base/label/label.js +0 -12
  45. package/dist/components/base/loading_icon/loading_icon.js +7 -10
  46. package/dist/components/base/markdown/markdown.js +1 -0
  47. package/dist/components/base/modal/modal.js +7 -27
  48. package/dist/components/base/new_dropdowns/base_dropdown/base_dropdown.js +0 -25
  49. package/dist/components/base/new_dropdowns/constants.js +4 -2
  50. package/dist/components/base/new_dropdowns/listbox/listbox.js +0 -63
  51. package/dist/components/base/new_dropdowns/listbox/listbox_group.js +0 -2
  52. package/dist/components/base/new_dropdowns/listbox/listbox_item.js +0 -5
  53. package/dist/components/base/new_dropdowns/listbox/utils.js +0 -7
  54. package/dist/components/base/paginated_list/paginated_list.js +0 -15
  55. package/dist/components/base/pagination/pagination.js +14 -72
  56. package/dist/components/base/path/path.js +0 -29
  57. package/dist/components/base/popover/popover.js +0 -5
  58. package/dist/components/base/search_box_by_click/search_box_by_click.js +1 -26
  59. package/dist/components/base/search_box_by_type/search_box_by_type.js +2 -12
  60. package/dist/components/base/segmented_control/segmented_control.js +0 -10
  61. package/dist/components/base/skeleton_loader/skeleton_loader.js +0 -19
  62. package/dist/components/base/skeleton_loading/skeleton_loading.js +0 -3
  63. package/dist/components/base/sorting/sorting.js +1 -9
  64. package/dist/components/base/sorting/sorting_item.js +4 -6
  65. package/dist/components/base/table/table.js +0 -4
  66. package/dist/components/base/tabs/tab/tab.js +2 -6
  67. package/dist/components/base/tabs/tabs/scrollable_tabs.js +0 -21
  68. package/dist/components/base/tabs/tabs/tabs.js +8 -33
  69. package/dist/components/base/toast/toast.js +3 -15
  70. package/dist/components/base/toggle/toggle.js +0 -18
  71. package/dist/components/base/token/token.js +0 -4
  72. package/dist/components/base/token_selector/token_container.js +0 -24
  73. package/dist/components/base/token_selector/token_selector.js +10 -61
  74. package/dist/components/base/token_selector/token_selector_dropdown.js +4 -32
  75. package/dist/components/charts/area/area.js +8 -32
  76. package/dist/components/charts/bar/bar.js +7 -19
  77. package/dist/components/charts/chart/chart.js +1 -22
  78. package/dist/components/charts/column/column.js +8 -18
  79. package/dist/components/charts/discrete_scatter/discrete_scatter.js +2 -13
  80. package/dist/components/charts/gauge/gauge.js +0 -15
  81. package/dist/components/charts/heatmap/heatmap.js +3 -16
  82. package/dist/components/charts/legend/legend.js +2 -24
  83. package/dist/components/charts/line/line.js +8 -34
  84. package/dist/components/charts/series_label/series_label.js +0 -12
  85. package/dist/components/charts/single_stat/single_stat.js +0 -8
  86. package/dist/components/charts/sparkline/sparkline.js +1 -16
  87. package/dist/components/charts/stacked_column/stacked_column.js +8 -26
  88. package/dist/components/charts/tooltip/tooltip.js +0 -6
  89. package/dist/components/mixins/button_mixin.js +0 -1
  90. package/dist/components/mixins/safe_link_mixin.js +0 -1
  91. package/dist/components/mixins/toolbox_mixin.js +0 -1
  92. package/dist/components/mixins/tooltip_mixin.js +1 -2
  93. package/dist/components/regions/empty_state/empty_state.js +0 -12
  94. package/dist/components/utilities/animated_number/animated_number.js +0 -16
  95. package/dist/components/utilities/friendly_wrap/friendly_wrap.js +0 -3
  96. package/dist/components/utilities/intersection_observer/intersection_observer.js +0 -7
  97. package/dist/components/utilities/intersperse/intersperse.js +3 -9
  98. package/dist/components/utilities/sprintf/sprintf.js +9 -23
  99. package/dist/components/utilities/truncate/truncate.js +0 -10
  100. package/dist/config.js +3 -4
  101. package/dist/directives/hover_load/hover_load.js +2 -8
  102. package/dist/directives/outside/get_event_like_time_stamp.js +4 -2
  103. package/dist/directives/outside/outside.js +5 -20
  104. package/dist/directives/resize_observer/resize_observer.js +0 -10
  105. package/dist/directives/safe_html/safe_html.js +5 -6
  106. package/dist/directives/safe_link/mock_data.js +1 -1
  107. package/dist/directives/safe_link/safe_link.js +0 -13
  108. package/dist/utils/breakpoints.js +0 -3
  109. package/dist/utils/charts/config.js +29 -42
  110. package/dist/utils/charts/constants.js +8 -8
  111. package/dist/utils/charts/mock_data.js +2 -2
  112. package/dist/utils/charts/story_config.js +1 -1
  113. package/dist/utils/charts/theme.js +1 -3
  114. package/dist/utils/charts/utils.js +2 -6
  115. package/dist/utils/constants.js +10 -7
  116. package/dist/utils/data_utils.js +5 -4
  117. package/dist/utils/datetime_utility.js +4 -4
  118. package/dist/utils/number_utils.js +7 -11
  119. package/dist/utils/stories_utils.js +1 -1
  120. package/dist/utils/story_decorators/container.js +0 -1
  121. package/dist/utils/string_utils.js +0 -14
  122. package/dist/utils/test_utils.js +3 -2
  123. package/dist/utils/use_fake_date.js +0 -4
  124. package/dist/utils/use_mock_intersection_observer.js +4 -19
  125. package/dist/utils/utils.js +5 -14
  126. package/package.json +3 -3
  127. package/src/components/base/pagination/pagination.vue +2 -2
@@ -7,7 +7,6 @@ const SUFFIX = '}';
7
7
  const START_SUFFIX = 'Start';
8
8
  const END_SUFFIX = 'End';
9
9
  const PLACE_HOLDER_REGEX = new RegExp(`(${PREFIX}[a-z]+[\\w-]*[a-z0-9]+${SUFFIX})`, 'gi');
10
-
11
10
  function groupPlaceholdersByStartTag() {
12
11
  let placeholders = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
13
12
  return Object.entries(placeholders).reduce((acc, _ref) => {
@@ -19,17 +18,15 @@ function groupPlaceholdersByStartTag() {
19
18
  return acc;
20
19
  }, {});
21
20
  }
22
-
23
21
  function getPlaceholderDefinition(chunk, placeholdersByStartTag) {
24
22
  const tagName = chunk.slice(PREFIX.length, -SUFFIX.length);
25
-
26
23
  if (_has(placeholdersByStartTag, tagName)) {
27
24
  // Use provided custom placeholder definition
28
- return { ...placeholdersByStartTag[tagName],
25
+ return {
26
+ ...placeholdersByStartTag[tagName],
29
27
  tagName
30
28
  };
31
29
  }
32
-
33
30
  if (tagName.endsWith(START_SUFFIX)) {
34
31
  // Tag conforms to default start/end tag naming convention
35
32
  const slotName = tagName.slice(0, -START_SUFFIX.length);
@@ -39,14 +36,12 @@ function getPlaceholderDefinition(chunk, placeholdersByStartTag) {
39
36
  tagName
40
37
  };
41
38
  }
42
-
43
39
  return {
44
40
  slotName: tagName,
45
41
  endTag: undefined,
46
42
  tagName
47
43
  };
48
44
  }
49
-
50
45
  var script = {
51
46
  functional: true,
52
47
  props: {
@@ -57,7 +52,6 @@ var script = {
57
52
  type: String,
58
53
  required: true
59
54
  },
60
-
61
55
  /**
62
56
  * An object mapping slot names to custom start/end placeholders. Use this
63
57
  * to avoid changing an existing message, and in turn invalidating existing
@@ -70,7 +64,6 @@ var script = {
70
64
  validator: value => Object.values(value).every(tagPair => Array.isArray(tagPair) && tagPair.length === 2 && tagPair.every(_isString))
71
65
  }
72
66
  },
73
-
74
67
  /**
75
68
  * Available slots are determined by the placeholders in the provided
76
69
  * message prop. For example, a message of "Written by %{author}" has
@@ -88,61 +81,54 @@ var script = {
88
81
  // This approach is also more performant, as it minimizes (relatively) object
89
82
  // creation/garbage collection, which is important given how frequently this
90
83
  // code may run on a given page.
84
+
91
85
  let i = 0;
92
86
  const vnodes = [];
93
87
  const slots = context.scopedSlots;
94
88
  const chunks = context.props.message.split(PLACE_HOLDER_REGEX);
95
89
  const placeholdersByStartTag = groupPlaceholdersByStartTag(context.props.placeholders);
96
-
97
90
  while (i < chunks.length) {
98
- const chunk = chunks[i]; // Skip past this chunk now we have it
99
-
91
+ const chunk = chunks[i];
92
+ // Skip past this chunk now we have it
100
93
  i += 1;
101
-
102
94
  if (!PLACE_HOLDER_REGEX.test(chunk)) {
103
95
  // Not a placeholder, so pass through as-is
104
96
  vnodes.push(chunk);
105
97
  continue;
106
98
  }
107
-
108
99
  const {
109
100
  slotName,
110
101
  endTag,
111
102
  tagName
112
103
  } = getPlaceholderDefinition(chunk, placeholdersByStartTag);
113
-
114
104
  if (endTag) {
115
105
  // Peek ahead to find end placeholder, if any
116
106
  const indexOfEnd = chunks.indexOf(`${PREFIX}${endTag}${SUFFIX}`, i);
117
-
118
107
  if (indexOfEnd > -1) {
119
108
  // We have a valid start/end placeholder pair! Extract the content
120
109
  // between them and skip past the end placeholder
121
110
  const content = chunks.slice(i, indexOfEnd);
122
111
  i = indexOfEnd + 1;
123
-
124
112
  if (!_has(slots, slotName)) {
125
113
  // Slot hasn't been provided; return placeholders and content as-is
126
114
  vnodes.push(chunk, ...content, chunks[indexOfEnd]);
127
115
  continue;
128
- } // Provide content to provided scoped slot
129
-
116
+ }
130
117
 
118
+ // Provide content to provided scoped slot
131
119
  vnodes.push(slots[slotName]({
132
120
  content: content.join('')
133
121
  }));
134
122
  continue;
135
123
  }
136
- } // By process of elimination, chunk must be a plain placeholder
137
-
124
+ }
138
125
 
126
+ // By process of elimination, chunk must be a plain placeholder
139
127
  vnodes.push(_has(slots, tagName) ? slots[tagName]() : chunk);
140
128
  continue;
141
129
  }
142
-
143
130
  return vnodes;
144
131
  }
145
-
146
132
  };
147
133
 
148
134
  /* script */
@@ -18,7 +18,6 @@ var script = {
18
18
  type: String,
19
19
  required: true
20
20
  },
21
-
22
21
  /**
23
22
  * Ellipsis position
24
23
  */
@@ -28,7 +27,6 @@ var script = {
28
27
  default: POSITION.END,
29
28
  validator: value => Object.values(POSITION).includes(value)
30
29
  },
31
-
32
30
  /**
33
31
  * Display the full text in a tooltip only if it is being truncated
34
32
  */
@@ -38,30 +36,24 @@ var script = {
38
36
  default: false
39
37
  }
40
38
  },
41
-
42
39
  data() {
43
40
  return {
44
41
  isTruncated: false
45
42
  };
46
43
  },
47
-
48
44
  computed: {
49
45
  middleIndex() {
50
46
  return Math.floor(this.text.length / 2);
51
47
  },
52
-
53
48
  first() {
54
49
  return this.text.slice(0, this.middleIndex);
55
50
  },
56
-
57
51
  last() {
58
52
  return this.text.slice(this.middleIndex);
59
53
  },
60
-
61
54
  isTooltipDisabled() {
62
55
  return !this.withTooltip || !this.isTruncated;
63
56
  }
64
-
65
57
  },
66
58
  watch: {
67
59
  withTooltip(withTooltip) {
@@ -69,7 +61,6 @@ var script = {
69
61
  this.checkTruncationState();
70
62
  }
71
63
  }
72
-
73
64
  },
74
65
  methods: {
75
66
  checkTruncationState() {
@@ -77,7 +68,6 @@ var script = {
77
68
  this.isTruncated = this.$refs.text.scrollWidth > this.$refs.text.offsetWidth;
78
69
  }
79
70
  }
80
-
81
71
  }
82
72
  };
83
73
 
package/dist/config.js CHANGED
@@ -9,6 +9,7 @@ const tooltipGlobalConfig = {
9
9
  customClass: 'gl-tooltip',
10
10
  delay: tooltipDelay
11
11
  };
12
+
12
13
  /**
13
14
  * Guard against nonexistent localStorage,
14
15
  * or corrupted localStorage
@@ -17,16 +18,14 @@ const tooltipGlobalConfig = {
17
18
  * - in iframe usage in Chrome if embedded on another domain
18
19
  * - tests / node
19
20
  */
20
-
21
21
  try {
22
22
  const glTooltipDelay = localStorage.getItem('gl-tooltip-delay');
23
-
24
23
  if (glTooltipDelay) {
25
24
  tooltipGlobalConfig.delay = JSON.parse(glTooltipDelay);
26
25
  }
27
- } catch (e) {// localStorage doesn't exist (or the value is not properly formatted)
26
+ } catch (e) {
27
+ // localStorage doesn't exist (or the value is not properly formatted)
28
28
  }
29
-
30
29
  const setConfigs = () => {
31
30
  Vue.use(BVConfigPlugin, {
32
31
  BFormText: bFormTextGlobalConfig,
@@ -3,46 +3,40 @@ import isFunction from 'lodash/isFunction';
3
3
  const DELAY_ON_HOVER = 100;
4
4
  let mouseOverTimer;
5
5
  let mouseOverHandler;
6
-
7
6
  const bind = (el, _ref) => {
8
7
  let {
9
8
  value: loadHandler
10
9
  } = _ref;
11
-
12
10
  if (!isFunction(loadHandler)) {
13
11
  throw TypeError('Directive value must be a function');
14
12
  }
15
-
16
13
  const mouseOutHandler = () => {
17
14
  if (mouseOverTimer) {
18
15
  clearTimeout(mouseOverTimer);
19
16
  mouseOverTimer = undefined;
20
17
  }
21
18
  };
22
-
23
19
  mouseOverHandler = () => {
24
20
  el.addEventListener('mouseout', mouseOutHandler, {
25
21
  passive: true
26
22
  });
27
23
  mouseOverTimer = setTimeout(() => {
28
- loadHandler(el); // Only execute once
24
+ loadHandler(el);
29
25
 
26
+ // Only execute once
30
27
  el.removeEventListener('mouseover', mouseOverHandler, true);
31
28
  el.removeEventListener('mouseout', mouseOutHandler);
32
29
  mouseOverTimer = undefined;
33
30
  }, DELAY_ON_HOVER);
34
31
  };
35
-
36
32
  el.addEventListener('mouseover', mouseOverHandler, {
37
33
  capture: true,
38
34
  passive: true
39
35
  });
40
36
  };
41
-
42
37
  const unbind = el => {
43
38
  el.removeEventListener('mouseover', mouseOverHandler, true);
44
39
  };
45
-
46
40
  const HoverLoadDirective = {
47
41
  bind,
48
42
  unbind
@@ -4,9 +4,11 @@
4
4
  *
5
5
  * See the LICENSE file in this directory.
6
6
  */
7
+
7
8
  const {
8
9
  performance
9
10
  } = window;
11
+
10
12
  /**
11
13
  * Get a current timestamp that can be meaningfully compared to an event's
12
14
  * `timeStamp` property.
@@ -22,8 +24,8 @@ const {
22
24
  *
23
25
  * @returns {number}
24
26
  */
25
-
26
- const getEventLikeTimeStamp = // If the event timestamp, although evaluated AFTER the Date.now(), is
27
+ const getEventLikeTimeStamp =
28
+ // If the event timestamp, although evaluated AFTER the Date.now(), is
27
29
  // smaller, it means the event is using a hi-res timestamp, and we need to
28
30
  // use the hi-res version for event listener timestamps as well.
29
31
  typeof (performance === null || performance === void 0 ? void 0 : performance.now) === 'function' && Date.now() > document.createEvent('Event').timeStamp ? () => performance.now() : () => Date.now();
@@ -3,27 +3,25 @@ import { getEventLikeTimeStamp } from './get_event_like_time_stamp';
3
3
  /**
4
4
  * Map<HTMLElement, { bindTimeStamp: number, callback: Function }>
5
5
  */
6
-
7
6
  const callbacks = new Map();
7
+
8
8
  /**
9
9
  * Is a global listener already set up?
10
10
  */
11
-
12
11
  let listening = false;
13
-
14
12
  const globalListener = event => {
15
13
  callbacks.forEach((_ref, element) => {
16
14
  let {
17
15
  bindTimeStamp,
18
16
  callback
19
17
  } = _ref;
20
-
21
- if ( // Ignore events that aren't targeted outside the element
22
- element.contains(event.target) || // Only consider events triggered after the directive was bound
18
+ if (
19
+ // Ignore events that aren't targeted outside the element
20
+ element.contains(event.target) ||
21
+ // Only consider events triggered after the directive was bound
23
22
  event.timeStamp <= bindTimeStamp) {
24
23
  return;
25
24
  }
26
-
27
25
  try {
28
26
  callback(event);
29
27
  } catch (e) {
@@ -34,41 +32,33 @@ const globalListener = event => {
34
32
  }
35
33
  });
36
34
  };
37
-
38
35
  const startListening = () => {
39
36
  if (listening) {
40
37
  return;
41
38
  }
42
-
43
39
  document.addEventListener('click', globalListener, {
44
40
  capture: true
45
41
  });
46
42
  listening = true;
47
43
  };
48
-
49
44
  const stopListening = () => {
50
45
  if (!listening) {
51
46
  return;
52
47
  }
53
-
54
48
  document.removeEventListener('click', globalListener);
55
49
  listening = false;
56
50
  };
57
-
58
51
  const bind = (el, _ref2) => {
59
52
  let {
60
53
  value,
61
54
  arg = 'click'
62
55
  } = _ref2;
63
-
64
56
  if (typeof value !== 'function') {
65
57
  throw new Error(`[GlOutsideDirective] Value must be a function; got ${typeof value}!`);
66
58
  }
67
-
68
59
  if (arg !== 'click') {
69
60
  throw new Error(`[GlOutsideDirective] Cannot bind ${arg} events; only click events are currently supported!`);
70
61
  }
71
-
72
62
  if (callbacks.has(el)) {
73
63
  // This element is already bound. This is possible if two components, which
74
64
  // share the same root node, (i.e., one is a higher-order component
@@ -81,25 +71,20 @@ const bind = (el, _ref2) => {
81
71
  // element.
82
72
  return;
83
73
  }
84
-
85
74
  if (!listening) {
86
75
  startListening();
87
76
  }
88
-
89
77
  callbacks.set(el, {
90
78
  bindTimeStamp: getEventLikeTimeStamp(),
91
79
  callback: value
92
80
  });
93
81
  };
94
-
95
82
  const unbind = el => {
96
83
  callbacks.delete(el);
97
-
98
84
  if (callbacks.size === 0) {
99
85
  stopListening();
100
86
  }
101
87
  };
102
-
103
88
  const OutsideDirective = {
104
89
  bind,
105
90
  unbind
@@ -1,12 +1,10 @@
1
1
  import isFunction from 'lodash/isFunction';
2
2
 
3
3
  let observer = null;
4
-
5
4
  const attachObserver = (el, resizeHandler) => {
6
5
  if (!isFunction(resizeHandler)) {
7
6
  throw TypeError('directive value must be a function');
8
7
  }
9
-
10
8
  if (!observer) {
11
9
  // the observer instance is shared for performance reasons
12
10
  // more information: https://github.com/WICG/ResizeObserver/issues/59
@@ -16,45 +14,37 @@ const attachObserver = (el, resizeHandler) => {
16
14
  });
17
15
  });
18
16
  }
19
-
20
17
  el.glResizeHandler = resizeHandler;
21
18
  observer.observe(el);
22
19
  };
23
-
24
20
  const detachObserver = el => {
25
21
  if (el.glResizeHandler) {
26
22
  var _observer;
27
-
28
23
  delete el.glResizeHandler;
29
24
  (_observer = observer) === null || _observer === void 0 ? void 0 : _observer.unobserve(el);
30
25
  }
31
26
  };
32
-
33
27
  const GlResizeObserverDirective = {
34
28
  bind(el, _ref) {
35
29
  let {
36
30
  value: resizeHandler,
37
31
  arg: enabled = true
38
32
  } = _ref;
39
-
40
33
  if (enabled) {
41
34
  attachObserver(el, resizeHandler);
42
35
  }
43
36
  },
44
-
45
37
  update(el, _ref2) {
46
38
  let {
47
39
  value: resizeHandler,
48
40
  arg: enabled = true
49
41
  } = _ref2;
50
-
51
42
  if (enabled) {
52
43
  attachObserver(el, resizeHandler);
53
44
  } else {
54
45
  detachObserver(el);
55
46
  }
56
47
  },
57
-
58
48
  unbind: detachObserver
59
49
  };
60
50
 
@@ -3,30 +3,29 @@ import { forbiddenDataAttrs } from './constants';
3
3
 
4
4
  const {
5
5
  sanitize
6
- } = DOMPurify; // Mitigate against future dompurify mXSS bypasses by
6
+ } = DOMPurify;
7
+
8
+ // Mitigate against future dompurify mXSS bypasses by
7
9
  // avoiding additional serialize/parse round trip.
8
10
  // See https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/1782
9
11
  // and https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2127
10
12
  // for more details.
11
-
12
13
  const DEFAULT_CONFIG = {
13
14
  RETURN_DOM_FRAGMENT: true,
14
15
  ALLOW_UNKNOWN_PROTOCOLS: true,
15
16
  FORBID_ATTR: [...forbiddenDataAttrs]
16
17
  };
17
-
18
18
  const transform = (el, binding) => {
19
19
  if (binding.oldValue !== binding.value) {
20
20
  var _binding$arg;
21
-
22
- const config = { ...DEFAULT_CONFIG,
21
+ const config = {
22
+ ...DEFAULT_CONFIG,
23
23
  ...((_binding$arg = binding.arg) !== null && _binding$arg !== void 0 ? _binding$arg : {})
24
24
  };
25
25
  el.textContent = '';
26
26
  el.appendChild(sanitize(binding.value, config));
27
27
  }
28
28
  };
29
-
30
29
  const SafeHtmlDirective = {
31
30
  bind: transform,
32
31
  update: transform
@@ -1,6 +1,6 @@
1
1
  const absoluteUrls = ['http://example.org', 'http://example.org:8080', 'https://example.org', 'https://example.org:8080', 'https://192.168.1.1', 'ftp://192.168.1.1', 'mailto:someone@example.com'];
2
- /* eslint-disable no-script-url */
3
2
 
3
+ /* eslint-disable no-script-url */
4
4
  const javascriptUrls = ['javascript:', 'javascript:alert("XSS")', 'jav\tascript:alert("XSS");'];
5
5
  /* eslint-disable no-script-url */
6
6
 
@@ -7,25 +7,19 @@ const getBaseURL = () => {
7
7
  } = window.location;
8
8
  return `${protocol}//${host}`;
9
9
  };
10
-
11
10
  const isExternalURL = (target, hostname) => {
12
11
  return target === '_blank' && hostname !== window.location.hostname;
13
12
  };
14
-
15
13
  const secureRel = rel => {
16
14
  const rels = rel ? rel.trim().split(' ') : [];
17
-
18
15
  if (!rels.includes('noopener')) {
19
16
  rels.push('noopener');
20
17
  }
21
-
22
18
  if (!rels.includes('noreferrer')) {
23
19
  rels.push('noreferrer');
24
20
  }
25
-
26
21
  return rels.join(' ');
27
22
  };
28
-
29
23
  const isSafeURL = url => {
30
24
  try {
31
25
  const parsedURL = new URL(url, getBaseURL());
@@ -34,41 +28,34 @@ const isSafeURL = url => {
34
28
  return false;
35
29
  }
36
30
  };
37
-
38
31
  const transform = function (el) {
39
32
  let {
40
33
  arg: {
41
34
  skipSanitization = false
42
35
  } = {}
43
36
  } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
44
-
45
37
  if (skipSanitization) {
46
38
  return;
47
39
  }
48
-
49
40
  const {
50
41
  href,
51
42
  target,
52
43
  rel,
53
44
  hostname
54
45
  } = el;
55
-
56
46
  if (!isSafeURL(href)) {
57
47
  el.href = 'about:blank';
58
48
  }
59
-
60
49
  if (isExternalURL(target, hostname)) {
61
50
  el.rel = secureRel(rel);
62
51
  }
63
52
  };
64
-
65
53
  const SafeLinkDirective = {
66
54
  inserted: transform,
67
55
  update: function () {
68
56
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
69
57
  args[_key] = arguments[_key];
70
58
  }
71
-
72
59
  Vue.nextTick(() => {
73
60
  transform(...args);
74
61
  });
@@ -7,17 +7,14 @@ const breakpoints = {
7
7
  };
8
8
  const BreakpointInstance = {
9
9
  windowWidth: () => window.innerWidth,
10
-
11
10
  getBreakpointSize() {
12
11
  const windowWidth = this.windowWidth();
13
12
  const breakpoint = Object.keys(breakpoints).find(key => windowWidth > breakpoints[key]);
14
13
  return breakpoint;
15
14
  },
16
-
17
15
  isDesktop() {
18
16
  return ['xl', 'lg'].includes(this.getBreakpointSize());
19
17
  }
20
-
21
18
  };
22
19
 
23
20
  export default BreakpointInstance;