@atlassian/aui 9.4.1 → 9.4.4

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@atlassian/aui",
3
3
  "description": "Atlassian User Interface library",
4
- "version": "9.4.1",
4
+ "version": "9.4.4",
5
5
  "author": "Atlassian Pty Ltd.",
6
6
  "homepage": "https://aui.atlassian.com",
7
7
  "license": "Apache-2.0",
@@ -38,7 +38,7 @@
38
38
  "backbone": "1.4.0",
39
39
  "css.escape": "1.5.0",
40
40
  "fancy-file-input": "2.0.4",
41
- "jquery-ui": "1.12.1",
41
+ "jquery-ui": "1.13.0",
42
42
  "skatejs": "0.13.17",
43
43
  "skatejs-template-html": "0.0.0",
44
44
  "trim-extra-html-whitespace": "1.3.0",
@@ -884,6 +884,10 @@ var stringAttributeHandlerGenerator = function(attrName) {
884
884
  };
885
885
  };
886
886
 
887
+ const convertCssClassesToArray = function (spaceDelimitedClasses = '') {
888
+ return spaceDelimitedClasses.split(' ').map(str => str.trim()).filter(x => x);
889
+ }
890
+
887
891
  const ItemLinkEl = skate('aui-item-link', {
888
892
  template: template(
889
893
  '<a role="menuitem" tabindex="-1"><content></content></a>'
@@ -909,7 +913,16 @@ const ItemLinkEl = skate('aui-item-link', {
909
913
  anchor.removeAttribute('aria-controls');
910
914
  $(anchor).removeClass('aui-dropdown2-sub-trigger');
911
915
  }
912
- }
916
+ },
917
+ 'extra-classes': function (element, change) {
918
+ const anchor = element.children[0];
919
+ if (change.oldValue) {
920
+ anchor.classList.remove(...convertCssClassesToArray(change.oldValue));
921
+ }
922
+ if (change.newValue) {
923
+ anchor.classList.add(...convertCssClassesToArray(change.newValue));
924
+ }
925
+ },
913
926
  },
914
927
  });
915
928
 
@@ -1,10 +1,15 @@
1
1
  import createHeader from './internal/header/create-header';
2
2
  import skate from './internal/skate';
3
3
 
4
- const Header = skate('aui-header', {
5
- type: skate.type.CLASSNAME,
4
+ const Header = skate('aui-header-end', {
5
+ type: skate.type.ELEMENT,
6
6
  created: function (element) {
7
- createHeader(element);
7
+ const auiHeader = element.parentElement;
8
+ if (auiHeader && auiHeader.classList.contains('aui-header')) {
9
+ createHeader(auiHeader);
10
+ } else {
11
+ console.log('Could not async. initialise aui-header');
12
+ }
8
13
  }
9
14
  });
10
15
 
@@ -1,5 +1,5 @@
1
1
  import format from './format';
2
- import globalize from './internal/globalize';
2
+ import { putOnI18nIfAbsent } from './internal/globalize';
3
3
  import keys from './internal/i18n/aui';
4
4
 
5
5
  /**
@@ -29,4 +29,8 @@ export {
29
29
  * aliases for I18n or export it from here using 'default'. Webpack transforms it then to
30
30
  * 'd.default.getText' and it won't match.
31
31
  **/
32
- globalize('I18n', I18n);
32
+ // eslint-disable-next-line guard-for-in
33
+ for (const property in I18n) {
34
+ // AUI-5431 Add to global namespace, but do not override what is set by the WRM
35
+ putOnI18nIfAbsent(property, I18n[property]);
36
+ }
@@ -1,4 +1,11 @@
1
1
  const NAMESPACE = 'AJS';
2
+ const I18N_OBJECT_NAME = 'I18n';
3
+
4
+ function initNamespace() {
5
+ if (typeof window[NAMESPACE] !== 'object') {
6
+ window[NAMESPACE] = {};
7
+ }
8
+ }
2
9
 
3
10
  /**
4
11
  * Makes given value available globally under window[name] attribute.
@@ -14,9 +21,19 @@ const NAMESPACE = 'AJS';
14
21
  * @returns exposed value
15
22
  */
16
23
  export default function globalize (name, value) {
17
- if (typeof window[NAMESPACE] !== 'object') {
18
- window[NAMESPACE] = {};
19
- }
24
+ initNamespace();
20
25
 
21
26
  return window[NAMESPACE][name] = value;
22
27
  }
28
+
29
+ export function putOnI18nIfAbsent (name, value) {
30
+ initNamespace();
31
+
32
+ if (typeof window[NAMESPACE][I18N_OBJECT_NAME] !== 'object') {
33
+ window[NAMESPACE][I18N_OBJECT_NAME] = {};
34
+ }
35
+
36
+ if (typeof window[NAMESPACE][I18N_OBJECT_NAME][name] === 'undefined') {
37
+ window[NAMESPACE][I18N_OBJECT_NAME][name] = value;
38
+ }
39
+ }
@@ -213,6 +213,10 @@ Header.prototype = {
213
213
  $navItemDropdown.addClass('aui-dropdown2-sub-menu');
214
214
  $navItemDropdown.appendTo('body');
215
215
  }
216
+ if ($navItemTrigger.get(0).hasAttribute('data-aui-extra-classes')) { // an opt-in behaviour
217
+ const extraClasses = Array.from($navItemTrigger.get(0).classList).filter(cls => !cls.startsWith('aui-'));
218
+ moreDropdownItemEl.setAttribute('extra-classes', extraClasses.join(' '));
219
+ }
216
220
  skate.init(moreDropdownItemEl);
217
221
  template.wrap(moreDropdownItemEl).textContent = $navItemTrigger.text();
218
222
 
@@ -37,6 +37,17 @@ const defaultOptions = {
37
37
 
38
38
  let $sharedTip;
39
39
 
40
+ const getTipNode = () => {
41
+ return $sharedTip && $sharedTip.get(0);
42
+ }
43
+
44
+ const toggleTooltipVisibility = (shouldBeHidden = false) => {
45
+ const tipNode = getTipNode();
46
+ if (tipNode) {
47
+ tipNode.classList.toggle('assistive', shouldBeHidden)
48
+ }
49
+ }
50
+
40
51
  class Tooltip {
41
52
  constructor(triggerElement, options) {
42
53
  this.triggerElement = triggerElement;
@@ -79,15 +90,8 @@ class Tooltip {
79
90
  this.$triggerElement.off(`.${pluginKey}`);
80
91
  }
81
92
 
82
- getFloatingTip() {
93
+ buildTip(title) {
83
94
  const options = this.options;
84
-
85
- let title = typeof options.title === 'function' ?
86
- options.title :
87
- typeof options.title === 'string' ?
88
- () => options.title :
89
- () => this.originalTitle || '';
90
-
91
95
  if ($sharedTip === undefined) {
92
96
  $sharedTip =
93
97
  $(`<div id="${AUI_TOOLTIP_ID}" class="${AUI_TOOLTIP_CLASS_NAME} assistive" role="tooltip"><p class="aui-tooltip-content"></p></div>`)
@@ -96,23 +100,35 @@ class Tooltip {
96
100
  }
97
101
 
98
102
  if (options.html) {
99
- $sharedTip.find('.aui-tooltip-content').html(title.call(this.triggerElement));
103
+ $sharedTip.find('.aui-tooltip-content').html(title);
100
104
  } else {
101
- $sharedTip.find('.aui-tooltip-content').text(title.call(this.triggerElement));
105
+ $sharedTip.find('.aui-tooltip-content').text(title);
102
106
  }
103
-
104
107
  return $sharedTip;
105
108
  }
106
109
 
110
+ getTipTitle() {
111
+ const options = this.options;
112
+
113
+ let title = typeof options.title === 'function' ?
114
+ options.title :
115
+ typeof options.title === 'string' ?
116
+ () => options.title :
117
+ () => this.originalTitle || '';
118
+
119
+ let actualTitle = title.call(this.triggerElement);
120
+ return (actualTitle.trim().length === 0) ? undefined : actualTitle;
121
+ }
122
+
107
123
  show() {
108
- if (this.enabled === false) {
124
+ const tipTitle = this.getTipTitle();
125
+ if (this.enabled === false || !tipTitle) {
109
126
  return;
110
127
  }
128
+
111
129
  this.hide();
112
130
  const triggerElement = this.triggerElement;
113
-
114
131
  const placement = GRAVITY_MAP[this.options.gravity];
115
-
116
132
  clearTimeout(this.popperTimeout);
117
133
 
118
134
  if (typeof this.options.suppress === 'function') {
@@ -121,9 +137,9 @@ class Tooltip {
121
137
  }
122
138
  }
123
139
 
140
+ const tipNode = this.buildTip(tipTitle).get(0);
124
141
  this.popperTimeout = setTimeout(() => {
125
- const tipNode = this.getFloatingTip().get(0);
126
- tipNode.classList.remove('assistive');
142
+ this.showTooltip();
127
143
 
128
144
  this.popperInstance = createPopper(triggerElement, tipNode, {
129
145
  placement,
@@ -139,12 +155,11 @@ class Tooltip {
139
155
 
140
156
  $(window).on(`scroll.${pluginKey}`, () => this.hide());
141
157
  }, AUI_TOOLTIP_TIMEOUT);
158
+
142
159
  }
143
160
 
144
161
  hide() {
145
- const tipNode = this.getFloatingTip().get(0);
146
- tipNode.classList.add('assistive');
147
-
162
+ this.hideTooltip();
148
163
  clearTimeout(this.popperTimeout);
149
164
 
150
165
  if (this.popperInstance) {
@@ -154,6 +169,14 @@ class Tooltip {
154
169
  $(window).off(`scroll.${pluginKey}`);
155
170
  }
156
171
 
172
+ showTooltip() {
173
+ toggleTooltipVisibility(false);
174
+ }
175
+
176
+ hideTooltip() {
177
+ toggleTooltipVisibility(true);
178
+ }
179
+
157
180
  enable() {
158
181
  this.enabled = true;
159
182
  }
@@ -191,7 +214,7 @@ $.fn.tooltip = function (arg) {
191
214
 
192
215
  // Get the tooltip instance assigned to the first element in the collection
193
216
  if (arg === true) {
194
- const firstDomNode = $collection.get(0)
217
+ const firstDomNode = $collection.get(0);
195
218
  return getTooltipInstance(firstDomNode);
196
219
  }
197
220
 
@@ -136,6 +136,9 @@ $.fn.ajaxSubmit = function(options) {
136
136
  var oldSuccess = options.success || function(){};
137
137
  callbacks.push(function(data) {
138
138
  var fn = options.replaceTarget ? 'replaceWith' : 'html';
139
+ // Validate `data` through `HTML encoding` when passed `data` is passed
140
+ // to `html()`, as suggested in https://github.com/jquery-form/form/issues/464
141
+ fn == 'html' ? data = $.parseHTML($("<div>").text(data).html()) : '';
139
142
  $(options.target)[fn](data).each(oldSuccess, arguments);
140
143
  });
141
144
  }
@@ -428,7 +431,10 @@ $.fn.ajaxSubmit = function(options) {
428
431
  return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
429
432
  };
430
433
  var parseJSON = $.parseJSON || function(s) {
431
- return window['eval']('(' + s + ')');
434
+ // Arise an error resolvable including jquery instead of
435
+ // making a new function using unsanitized inputs
436
+ window.console.error('jquery.parseJSON is undefined');
437
+ return null;
432
438
  };
433
439
 
434
440
  var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4