@atlassian/atlassian-connect-js 5.3.190

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 (190) hide show
  1. package/.depcheckrc.json +16 -0
  2. package/.editorconfig +9 -0
  3. package/.envrc +5 -0
  4. package/.eslintignore +12 -0
  5. package/.eslintrc +31 -0
  6. package/.husky/pre-commit +11 -0
  7. package/.lintstagedrc.js +6 -0
  8. package/.netrc +1 -0
  9. package/.npmrc-public +4 -0
  10. package/.nvmrc +1 -0
  11. package/LICENSE +3 -0
  12. package/README.md +281 -0
  13. package/bitbucket-pipelines.yml +33 -0
  14. package/build/bin/bin-helper.js +29 -0
  15. package/build/bin/npm-postinstall.js +9 -0
  16. package/build/configs/append-sourcemapping.js +13 -0
  17. package/build/configs/availabletasks.js +15 -0
  18. package/build/configs/clean.js +12 -0
  19. package/build/configs/concat.js +44 -0
  20. package/build/configs/copy.js +32 -0
  21. package/build/configs/index.js +19 -0
  22. package/build/configs/jshint.js +9 -0
  23. package/build/configs/karma.js +11 -0
  24. package/build/configs/replace.js +10 -0
  25. package/build/configs/requirejs.js +187 -0
  26. package/build/configs/saucelabs-launchers.js +30 -0
  27. package/build/configs/shell.js +24 -0
  28. package/build/configs/uglify.js +15 -0
  29. package/build/configs/watch.js +45 -0
  30. package/build/end.frag +13 -0
  31. package/build/start.frag +18 -0
  32. package/bundlesize.config.json +14 -0
  33. package/dist/connect-host.css +225 -0
  34. package/dist/connect-host.js +13908 -0
  35. package/dist/connect-host.min.css +1 -0
  36. package/dist/iframe-fedramp.js +13663 -0
  37. package/dist/iframe.js +13663 -0
  38. package/dist/legacy-text-colors.css +245 -0
  39. package/dist/surfaces.css +11 -0
  40. package/dist/themes/atlaskit-tokens_dark-future.css +6 -0
  41. package/dist/themes/atlaskit-tokens_dark.css +394 -0
  42. package/dist/themes/atlaskit-tokens_legacy-dark.css +394 -0
  43. package/dist/themes/atlaskit-tokens_legacy-light.css +394 -0
  44. package/dist/themes/atlaskit-tokens_light-future.css +6 -0
  45. package/dist/themes/atlaskit-tokens_light.css +394 -0
  46. package/dist/themes/atlaskit-tokens_shape.css +14 -0
  47. package/dist/themes/atlaskit-tokens_spacing.css +26 -0
  48. package/dist/themes/atlaskit-tokens_typography-adg3.css +25 -0
  49. package/dist/themes/atlaskit-tokens_typography-modernized.css +25 -0
  50. package/dist/themes/atlaskit-tokens_typography-refreshed.css +25 -0
  51. package/gulpfile.js +204 -0
  52. package/memleak-check/app.html +10 -0
  53. package/memleak-check/index.html +31 -0
  54. package/memleak-check/index.js +33 -0
  55. package/package.json +102 -0
  56. package/renovate.json +11 -0
  57. package/security-assistant.yml +2 -0
  58. package/spec/.eslintrc +10 -0
  59. package/spec/config/karma.base.conf.js +200 -0
  60. package/spec/config/karma.conf.js +20 -0
  61. package/spec/fixtures/base_dialog_component_tests.js +180 -0
  62. package/spec/mocks/mock_feature_flag.js +23 -0
  63. package/spec/tests/amd_spec.js +122 -0
  64. package/spec/tests/analytics_dispatcher_spec.js +429 -0
  65. package/spec/tests/analytics_performance_spec.js +41 -0
  66. package/spec/tests/button_spec.js +143 -0
  67. package/spec/tests/dialog_extension_spec.js +59 -0
  68. package/spec/tests/dialog_module_provider_spec.js +499 -0
  69. package/spec/tests/dialog_module_spec.js +395 -0
  70. package/spec/tests/dialog_spec.js +296 -0
  71. package/spec/tests/dialog_webitem_spec.js +183 -0
  72. package/spec/tests/dropdown_module_spec.js +77 -0
  73. package/spec/tests/env_module_spec.js +153 -0
  74. package/spec/tests/events_spec.js +77 -0
  75. package/spec/tests/extension_configuration_options_store_spec.js +25 -0
  76. package/spec/tests/flag_module_provider_spec.js +79 -0
  77. package/spec/tests/flag_module_spec.js +118 -0
  78. package/spec/tests/flag_spec.js +243 -0
  79. package/spec/tests/host-api_spec.js +220 -0
  80. package/spec/tests/iframe-create_spec.js +43 -0
  81. package/spec/tests/iframe_container_spec.js +19 -0
  82. package/spec/tests/iframe_spec.js +265 -0
  83. package/spec/tests/inline_dialog_spec.js +41 -0
  84. package/spec/tests/inline_dialog_webitem_spec.js +331 -0
  85. package/spec/tests/loading_indicator_spec.js +48 -0
  86. package/spec/tests/messages_module_spec.js +108 -0
  87. package/spec/tests/meta_spec.js +71 -0
  88. package/spec/tests/module_args_spec.js +52 -0
  89. package/spec/tests/observe_spec.js +73 -0
  90. package/spec/tests/public_events.spec.js +102 -0
  91. package/spec/tests/scroll_position_spec.js +109 -0
  92. package/spec/tests/theming_spec.js +594 -0
  93. package/spec/tests/util_spec.js +55 -0
  94. package/spec/tests/utils/base64_spec.js +20 -0
  95. package/spec/tests/utils/button_spec.js +11 -0
  96. package/spec/tests/utils/cookie_spec.js +19 -0
  97. package/spec/tests/utils/deprecate_spec.js +22 -0
  98. package/spec/tests/utils/dialog_spec.js +297 -0
  99. package/spec/tests/utils/host_util_spec.js +45 -0
  100. package/spec/tests/utils/iframe_spec.js +41 -0
  101. package/spec/tests/utils/jwt_spec.js +135 -0
  102. package/spec/tests/utils/url_spec.js +37 -0
  103. package/spec/tests/utils/waitUntilReadyNextTick.js +5 -0
  104. package/spec/tests/utils/webitem.js +219 -0
  105. package/spec/tests/webitem_spec.js +131 -0
  106. package/src/css/host/dialog.css +144 -0
  107. package/src/css/host/flags.css +5 -0
  108. package/src/css/host/host.css +64 -0
  109. package/src/css/host/messages.css +12 -0
  110. package/src/css/plugin/legacy-text-colors.less +55 -0
  111. package/src/css/plugin/surfaces.css +11 -0
  112. package/src/host/ACJSFrameworkAdaptor.js +44 -0
  113. package/src/host/actions/analytics_action.js +35 -0
  114. package/src/host/actions/button_actions.js +21 -0
  115. package/src/host/actions/dialog_actions.js +27 -0
  116. package/src/host/actions/dialog_extension_actions.js +25 -0
  117. package/src/host/actions/dom_event_actions.js +32 -0
  118. package/src/host/actions/dropdown_actions.js +12 -0
  119. package/src/host/actions/env_actions.js +57 -0
  120. package/src/host/actions/event_actions.js +33 -0
  121. package/src/host/actions/flag_actions.js +22 -0
  122. package/src/host/actions/iframe_actions.js +27 -0
  123. package/src/host/actions/inline_dialog_actions.js +26 -0
  124. package/src/host/actions/inline_dialog_webitem_actions.js +10 -0
  125. package/src/host/actions/jwt_actions.js +51 -0
  126. package/src/host/actions/loading_indicator_actions.js +10 -0
  127. package/src/host/actions/module_actions.js +14 -0
  128. package/src/host/actions/webitem_actions.js +29 -0
  129. package/src/host/components/button.js +112 -0
  130. package/src/host/components/dialog.js +447 -0
  131. package/src/host/components/dialog_extension.js +106 -0
  132. package/src/host/components/dialog_webitem.js +69 -0
  133. package/src/host/components/flag.js +102 -0
  134. package/src/host/components/iframe.js +130 -0
  135. package/src/host/components/iframe_container.js +38 -0
  136. package/src/host/components/inline_dialog.js +108 -0
  137. package/src/host/components/inline_dialog_webitem.js +157 -0
  138. package/src/host/components/loading_indicator.js +110 -0
  139. package/src/host/components/webitem.js +227 -0
  140. package/src/host/deprecate.js +20 -0
  141. package/src/host/dispatchers/analytics_dispatcher.js +512 -0
  142. package/src/host/dispatchers/event_dispatcher.js +46 -0
  143. package/src/host/dollar.js +8 -0
  144. package/src/host/host-api.js +325 -0
  145. package/src/host/iframe-create.js +7 -0
  146. package/src/host/index.js +108 -0
  147. package/src/host/module-providers.js +13 -0
  148. package/src/host/modules/_featureFlag.js +42 -0
  149. package/src/host/modules/_performance.js +54 -0
  150. package/src/host/modules/analytics.js +17 -0
  151. package/src/host/modules/dialog.js +496 -0
  152. package/src/host/modules/dropdown.js +255 -0
  153. package/src/host/modules/env.js +156 -0
  154. package/src/host/modules/events.js +28 -0
  155. package/src/host/modules/flag.js +170 -0
  156. package/src/host/modules/host.js +19 -0
  157. package/src/host/modules/inline-dialog.js +33 -0
  158. package/src/host/modules/messages.js +309 -0
  159. package/src/host/modules/page.js +29 -0
  160. package/src/host/modules/scroll-position.js +102 -0
  161. package/src/host/modules/theming.js +114 -0
  162. package/src/host/stores/extension_configuration_options_store.js +24 -0
  163. package/src/host/util.js +98 -0
  164. package/src/host/utils/access-narrowing-context.js +18 -0
  165. package/src/host/utils/base64.js +22 -0
  166. package/src/host/utils/button.js +10 -0
  167. package/src/host/utils/cookie.js +14 -0
  168. package/src/host/utils/dialog.js +239 -0
  169. package/src/host/utils/feature-flag.js +27 -0
  170. package/src/host/utils/iframe.js +23 -0
  171. package/src/host/utils/jwt.js +60 -0
  172. package/src/host/utils/observe.js +34 -0
  173. package/src/host/utils/removal-observer.js +30 -0
  174. package/src/host/utils/simplexdm.js +58 -0
  175. package/src/host/utils/url.js +23 -0
  176. package/src/host/utils/webitem.js +214 -0
  177. package/src/plugin/amd.js +115 -0
  178. package/src/plugin/analytics.js +84 -0
  179. package/src/plugin/deprecate.js +16 -0
  180. package/src/plugin/dialog.js +197 -0
  181. package/src/plugin/dollar.js +77 -0
  182. package/src/plugin/events-instance.js +2 -0
  183. package/src/plugin/events.js +246 -0
  184. package/src/plugin/extension_configuration_options_store.js +27 -0
  185. package/src/plugin/featureFlag.js +8 -0
  186. package/src/plugin/index.js +118 -0
  187. package/src/plugin/meta.js +14 -0
  188. package/src/plugin/public-events.js +73 -0
  189. package/src/plugin/theming.js +211 -0
  190. package/src/plugin/util.js +104 -0
@@ -0,0 +1,214 @@
1
+ import qs from 'query-string';
2
+ import Util from '../util';
3
+
4
+ function sanitizeTriggers(triggers) {
5
+ var onTriggers;
6
+ if(Array.isArray(triggers)) {
7
+ onTriggers = triggers.join(' ');
8
+ } else if (typeof triggers === 'string') {
9
+ onTriggers = triggers.trim();
10
+ }
11
+ return onTriggers;
12
+ }
13
+
14
+ function uniqueId(){
15
+ return 'webitem-' + Math.floor(Math.random() * 1000000000).toString(16);
16
+ }
17
+
18
+ /**
19
+ * LEGACY: get addon key by webitem for p2
20
+ * @param {string} cssClass
21
+ */
22
+ function getExtensionKey(cssClass){
23
+ var m = cssClass ? cssClass.match(/ap-plugin-key-([^\s]*)/) : null;
24
+ return Array.isArray(m) ? m[1] : false;
25
+ }
26
+
27
+ /**
28
+ * LEGACY: get module key by webitem for p2
29
+ * @param {string} cssClass
30
+ */
31
+ function getKey(cssClass){
32
+ var m = cssClass ? cssClass.match(/ap-module-key-([^\s]*)/) : null;
33
+ return Array.isArray(m) ? m[1] : false;
34
+ }
35
+
36
+ /**
37
+ * @param cssClass
38
+ */
39
+ function getTargetKey(cssClass){
40
+ var m = cssClass ? cssClass.match(/ap-target-key-([^\s]*)/) : null;
41
+ return Array.isArray(m) ? m[1] : false;
42
+ }
43
+
44
+ /**
45
+ * @param cssClass
46
+ * @returns {string}
47
+ */
48
+ function getFullKey(cssClass){
49
+ return getExtensionKey(cssClass) + '__' + getKey(cssClass);
50
+ }
51
+
52
+ function getModuleOptionsByAddonAndModuleKey(type, addonKey, moduleKey) {
53
+ var moduleType = type + 'Modules';
54
+ if(window._AP
55
+ && window._AP[moduleType]
56
+ && window._AP[moduleType][addonKey]
57
+ && window._AP[moduleType][addonKey][moduleKey]) {
58
+ return Util.extend({}, window._AP[moduleType][addonKey][moduleKey].options);
59
+ }
60
+ }
61
+
62
+ /**
63
+ * @param {string} type
64
+ * @param {string} cssClass
65
+ */
66
+ function getModuleOptionsForWebitem(type, cssClass){
67
+ var addon_key = getExtensionKey(cssClass);
68
+ var targetKey = getTargetKey(cssClass);
69
+ return getModuleOptionsByAddonAndModuleKey(type, addon_key, targetKey);
70
+ }
71
+
72
+ /**
73
+ * gets the connect config from the encoded webitem target (via the url)
74
+ * @param {JQuery} $target
75
+ * @param {string} cssClass
76
+ * @param {string|undefined} href
77
+ */
78
+ // eslint-disable-next-line complexity
79
+ function getConfigFromTarget($target, cssClass, href){
80
+ let url = href || $target.attr('href');
81
+ var convertedOptions = {};
82
+ var iframeData;
83
+ // adg3 has classes outside of a tag so look for href inside the a
84
+ if (!url) {
85
+ url = $target.find('a').attr('href');
86
+ }
87
+ if (url) {
88
+ var hashIndex = url.indexOf('#');
89
+ if (hashIndex >= 0) {
90
+ var hash = url.substring(hashIndex + 1);
91
+ try {
92
+ iframeData = JSON.parse(decodeURI(hash));
93
+ } catch (e) {
94
+ console.error('ACJS: cannot decode webitem anchor');
95
+ }
96
+ if (iframeData && window._AP && window._AP._convertConnectOptions) {
97
+ convertedOptions = window._AP._convertConnectOptions(iframeData);
98
+ } else {
99
+ console.error('ACJS: cannot convert webitem url to connect iframe options');
100
+ }
101
+
102
+ } else {
103
+ // The URL has no hash component so fall back to the old behaviour of providing:
104
+ // add-on key, module key, dialog module options and product context (from the webitem url).
105
+ // This may be the case for web items that were persisted prior to the new storage format whereby a hash
106
+ // fragment is added into the URL detailing the target module info. If this info is
107
+ // not present, the content resolver will be used to resolve the module after the web
108
+ // item is clicked.
109
+
110
+ // Old URL format detected. Falling back to old functionality
111
+ var fullKey = getFullKey(cssClass);
112
+ var type = isInlineDialogTrigger(cssClass) ? 'inlineDialog' : 'dialog';
113
+ var options = getModuleOptionsForWebitem(type, cssClass);
114
+ if(!options && window._AP && window._AP[type + 'Options']) {
115
+ options = Util.extend({}, window._AP[type + 'Options'][fullKey]) || {};
116
+ }
117
+ if(!options){
118
+ options = {};
119
+ console.warn('no webitem ' + type + 'Options for ' + fullKey);
120
+ }
121
+ options.productContext = options.productContext || {};
122
+ var query = qs.parse(qs.extract(url));
123
+ Util.extend(options.productContext, query);
124
+
125
+ convertedOptions = {
126
+ addon_key: getExtensionKey(cssClass),
127
+ key: getKey(cssClass),
128
+ options: options
129
+ };
130
+ }
131
+ }
132
+ return convertedOptions;
133
+ }
134
+
135
+ /**
136
+ * @param {string|string[]|null} classes
137
+ * @returns {boolean}
138
+ */
139
+ export function isInlineDialogTrigger(classes) {
140
+ return classes ? classes.includes('ap-inline-dialog') : false
141
+ }
142
+
143
+ /**
144
+ * @param {string|string[]|null} classes
145
+ * @returns {boolean}
146
+ */
147
+ export function isDialogTrigger(classes) {
148
+ return classes ? classes.includes('ap-dialog') : false
149
+ }
150
+
151
+ /**
152
+ * LEGACY - method for handling webitem options for p2
153
+ * @param {JQuery} $target
154
+ * @param {string} cssClass
155
+ * @param {string|undefined} href
156
+ */
157
+ function getOptionsForWebItem($target, cssClass, href) {
158
+ var fullKey = getFullKey(cssClass);
159
+
160
+ var type = isInlineDialogTrigger(cssClass) ? 'inlineDialog' : 'dialog';
161
+ var options = getModuleOptionsForWebitem(type, cssClass);
162
+ if(!options && window._AP && window._AP[type + 'Options']) {
163
+ options = Util.extend({}, window._AP[type + 'Options'][fullKey]) || {};
164
+ }
165
+ if(!options){
166
+ options = {};
167
+ console.warn('no webitem ' + type + 'Options for ' + fullKey);
168
+ }
169
+ options.productContext = options.productContext || {};
170
+ options.structuredContext = options.structuredContext || {};
171
+ // create product context from url params
172
+
173
+ var convertedConfig = getConfigFromTarget($target, cssClass, href);
174
+
175
+ if(convertedConfig && convertedConfig.options) {
176
+ Util.extend(options.productContext, convertedConfig.options.productContext);
177
+ Util.extend(options.structuredContext, convertedConfig.options.structuredContext);
178
+ options.contextJwt = convertedConfig.options.contextJwt;
179
+ }
180
+
181
+ return options;
182
+ }
183
+
184
+ /**
185
+ * @param {HTMLElement} target
186
+ * @param {string[]} attributeNames
187
+ * @returns {string[]}
188
+ */
189
+ export function collectParentElementAttributes(target, attributeNames) {
190
+ // Collect attributes from parent elements of the webitem
191
+ const attributes = [];
192
+ let current = target
193
+ let count = 0;
194
+ while (current && current !== document.body && count++ < 1000) {
195
+ for (let attributeName of attributeNames) {
196
+ const attribute = current.getAttribute(attributeName);
197
+ if (attribute) {
198
+ attributes.push(attribute);
199
+ }
200
+ }
201
+ current = current.parentElement;
202
+ }
203
+ return attributes;
204
+ }
205
+
206
+ export default {
207
+ sanitizeTriggers,
208
+ uniqueId,
209
+ getExtensionKey,
210
+ getKey,
211
+ getOptionsForWebItem,
212
+ getModuleOptionsByAddonAndModuleKey,
213
+ getConfigFromTarget,
214
+ };
@@ -0,0 +1,115 @@
1
+ import AP from 'simple-xdm/combined';
2
+
3
+ var modules = {};
4
+
5
+ function reqAll(deps, callback) {
6
+ var mods = [];
7
+ var i = 0;
8
+ var len = deps.length;
9
+ function addOne(mod) {
10
+ mods.push(mod);
11
+ if (mods.length === len) {
12
+ var exports = [];
13
+ var i = 0;
14
+ for (; i < len; i += 1) {
15
+ exports[i] = mods[i].exports;
16
+ }
17
+ if (callback) {
18
+ callback.apply(window, exports);
19
+ }
20
+ }
21
+ }
22
+ if (deps && deps.length > 0) {
23
+ for (; i < len; i += 1) {
24
+ reqOne(deps[i], addOne);
25
+ }
26
+ } else {
27
+ if (callback) {
28
+ callback();
29
+ }
30
+ }
31
+ }
32
+
33
+ function reqOne(name, callback) {
34
+ // naive impl that assumes all modules are already loaded
35
+ callback(getOrCreate(name));
36
+ }
37
+
38
+ function getOrCreate(name) {
39
+ // get defined module
40
+ if (modules[name]) {
41
+ return modules[name];
42
+ }
43
+
44
+ // get a host module
45
+ var hostModule = getFromHostModules(name);
46
+ if (hostModule) {
47
+ return modules[name] = hostModule
48
+ }
49
+
50
+ // create a new module
51
+ return modules[name] = {
52
+ name: name,
53
+ exports: function () {
54
+ function exports() {
55
+ var target = exports.__target__;
56
+ if (target) {
57
+ return target.apply(window, arguments);
58
+ }
59
+ }
60
+ return exports;
61
+ }()
62
+ };
63
+ }
64
+
65
+ function getFromHostModules(name) {
66
+ var module;
67
+ if (AP._hostModules) {
68
+ if (AP._hostModules[name]) {
69
+ module = AP._hostModules[name];
70
+ }
71
+ if (AP._hostModules._globals && AP._hostModules._globals[name]) {
72
+ module = AP._hostModules._globals[name];
73
+ }
74
+ if (module) {
75
+ return {
76
+ name: name,
77
+ exports: module
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ // define(name, objOrFn)
84
+ // define(name, deps, fn(dep1, dep2, ...))
85
+ export default {
86
+ define: function (name, deps, exports) {
87
+ var mod = getOrCreate(name);
88
+ var factory;
89
+ if (!exports) {
90
+ exports = deps;
91
+ deps = [];
92
+ }
93
+ if (exports) {
94
+ factory = typeof exports !== 'function' ? function () {
95
+ return exports;
96
+ } : exports;
97
+ reqAll(deps, function () {
98
+ var exports = factory.apply(window, arguments);
99
+ if (exports) {
100
+ if (typeof exports === 'function') {
101
+ mod.exports.__target__ = exports;
102
+ }
103
+ for (var k in exports) {
104
+ if (exports.hasOwnProperty(k)) {
105
+ mod.exports[k] = exports[k];
106
+ }
107
+ }
108
+ }
109
+ });
110
+ }
111
+ },
112
+ require: function (deps, callback) {
113
+ reqAll(typeof deps === 'string' ? [deps] : deps, callback);
114
+ }
115
+ };
@@ -0,0 +1,84 @@
1
+ import AP from 'simple-xdm/combined';
2
+ import {onCLS, onFCP, onLCP, onTTFB} from 'web-vitals';
3
+
4
+ function getMetrics() {
5
+ if (window.performance && window.performance.getEntries) {
6
+ let navigationEntries = window.performance.getEntriesByType('navigation');
7
+ if (navigationEntries && navigationEntries[0]) {
8
+ let timingInfo = navigationEntries[0];
9
+ // dns loookup time
10
+ let domainLookupTime = timingInfo.domainLookupEnd - timingInfo.domainLookupStart;
11
+ let connectStart = timingInfo.connectStart;
12
+ // if it's a tls connection, use the secure connection start instead
13
+ if (timingInfo.secureConnectionStart > 0) {
14
+ connectStart = timingInfo.secureConnectionStart;
15
+ }
16
+ // connection negotiation time
17
+ let connectionTime = timingInfo.connectEnd - connectStart;
18
+ // page body size
19
+ let decodedBodySize = timingInfo.decodedBodySize;
20
+ // time to load dom
21
+ let domContentLoadedTime = timingInfo.domContentLoadedEventEnd - timingInfo.domContentLoadedEventStart;
22
+ // time to download the page
23
+ let fetchTime = timingInfo.responseEnd - timingInfo.fetchStart;
24
+
25
+ return {
26
+ domainLookupTime,
27
+ connectionTime,
28
+ decodedBodySize,
29
+ domContentLoadedTime,
30
+ fetchTime
31
+ }
32
+ }
33
+ }
34
+ }
35
+
36
+ function sendMetrics() {
37
+ let metrics = getMetrics();
38
+ if (AP._analytics && AP._analytics.trackIframePerformanceMetrics) {
39
+ AP._analytics.trackIframePerformanceMetrics(metrics);
40
+ }
41
+ }
42
+
43
+
44
+ function setupWebVitals(timeout) {
45
+ let metrics = {};
46
+
47
+ const collectMetrics = (source) => {
48
+ if (Object.keys(metrics).length > 0) {
49
+ console.log(`[web-vitals] Sending metrics triggered by: ${source}`, metrics);
50
+ if (AP._analytics && AP._analytics.trackWebVitals) {
51
+ AP._analytics.trackWebVitals(metrics);
52
+ metrics = {};
53
+ }
54
+ }
55
+ }
56
+
57
+ // Report all available metrics whenever the page is backgrounded or unloaded.
58
+ // https://github.com/GoogleChrome/web-vitals/blob/main/README.md#batch-multiple-reports-together
59
+ addEventListener('visibilitychange', () => {
60
+ if (document.visibilityState === 'hidden') {
61
+ collectMetrics('visibility change');
62
+ }
63
+ });
64
+
65
+ Promise.all([onCLS, onFCP, onLCP, onTTFB].map(collector => new Promise(resolve => {
66
+ collector(metric => {
67
+ const {name, value} = metric;
68
+ // Copied from https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/performance/browser-metrics/src/observer/web-vitals-observer.ts#web-vitals-observer.ts-36
69
+ // round FCP, LCP, TTFB to nearest integer.
70
+ // CLS is rounded to two decimal places.
71
+ const metricName = name.toLowerCase();
72
+ metrics[`metric:${metricName}`] = metricName === 'cls' ? parseFloat(value.toFixed(2)) : Math.round(value);
73
+ resolve();
74
+ });
75
+ }))).then(() => collectMetrics('all collected'));
76
+
77
+ // Collect any metrics we can after the timeout, if they haven't already been collected.
78
+ setTimeout(() => collectMetrics('timeout'), timeout);
79
+ }
80
+
81
+ export default {
82
+ sendMetrics,
83
+ setupWebVitals
84
+ }
@@ -0,0 +1,16 @@
1
+ import AP from 'simple-xdm/combined';
2
+
3
+ export default function (fn, name, alternate, sinceVersion) {
4
+ let called = false;
5
+ return (...args) => {
6
+ if (!called && typeof console !== 'undefined' && console.warn) {
7
+ called = true;
8
+ console.warn(`DEPRECATED API - ${name} has been deprecated ${sinceVersion ? `since ACJS ${sinceVersion}` : 'in ACJS'}` +
9
+ ` and will be removed in a future release. ${ alternate ? `Use ${alternate} instead.` : 'No alternative will be provided.' }`);
10
+ if(AP._analytics) {
11
+ AP._analytics.trackDeprecatedMethodUsed(name);
12
+ }
13
+ }
14
+ return fn(...args);
15
+ };
16
+ };
@@ -0,0 +1,197 @@
1
+ import AP from 'simple-xdm/combined';
2
+ import deprecate from './deprecate';
3
+ import EventsInstance from './events-instance';
4
+
5
+ let customButtonIncrement = 1;
6
+
7
+ const getCustomData = deprecate(() => {
8
+ return AP._data.options.customData;
9
+ }, 'AP.dialog.customData', 'AP.dialog.getCustomData()', '5.0');
10
+
11
+ if(AP._hostModules && AP._hostModules.dialog) {
12
+ /**
13
+ * Returns the custom data Object passed to the dialog at creation.
14
+ * @noDemo
15
+ * @deprecated after August 2017 | Please use <code>dialog.getCustomData(callback)</code> instead.
16
+ * @name customData
17
+ * @memberOf module:Dialog
18
+ * @ignore
19
+ * @example
20
+ * var myDataVariable = AP.dialog.customData.myDataVariable;
21
+ *
22
+ * @return {Object} Data Object passed to the dialog on creation.
23
+ */
24
+ Object.defineProperty(AP._hostModules.dialog, 'customData', {
25
+ get: getCustomData
26
+ });
27
+ Object.defineProperty(AP.dialog, 'customData', {
28
+ get: getCustomData
29
+ });
30
+
31
+ AP.dialog._disableCloseOnSubmit = false;
32
+ AP.dialog.disableCloseOnSubmit = function(){
33
+ AP.dialog._disableCloseOnSubmit = true;
34
+ }
35
+
36
+ }
37
+
38
+ const dialogHandlers = {};
39
+
40
+ EventsInstance.onAny(eventDelegator);
41
+ function eventDelegator(name, args) {
42
+ let dialogEventMatch = name.match(/^dialog\.(\w+)/);
43
+ if(!dialogEventMatch) {
44
+ return;
45
+ }
46
+ if(name === 'dialog.button.click') {
47
+ customButtonEvent(args.button.identifier, args);
48
+ } else {
49
+ submitOrCancelEvent(dialogEventMatch[1], args);
50
+ }
51
+ }
52
+
53
+ function customButtonEvent(buttonIdentifier, args) {
54
+ var callbacks = dialogHandlers[buttonIdentifier];
55
+ if(callbacks && callbacks.length !== 0){
56
+ try{
57
+ callbacks.forEach((callback) => {
58
+ callback.call(null, args);
59
+ });
60
+ } catch (err) {
61
+ console.error(err);
62
+ }
63
+ }
64
+ }
65
+
66
+ function submitOrCancelEvent(name, args) {
67
+ let handlers = dialogHandlers[name];
68
+ let shouldClose = name !== 'close';
69
+ var context = null;
70
+ // ignore events that are triggered by button clicks
71
+ // allow dialog.close through for close on ESC
72
+ if (shouldClose && typeof args.button === 'undefined') {
73
+ return;
74
+ }
75
+
76
+ // if the submit button has been set to not close on click
77
+ if(name === 'submit' && AP.dialog._disableCloseOnSubmit) {
78
+ shouldClose = false;
79
+ }
80
+
81
+ try {
82
+ if (handlers) {
83
+ if(args && args.button && args.button.name) {
84
+ context = AP.dialog.getButton(args.button.name);
85
+ }
86
+ shouldClose = handlers.reduce((result, cb) => cb.call(context, args) && result, shouldClose);
87
+ }
88
+ } catch (err) {
89
+ console.error(err);
90
+ } finally {
91
+ const shouldRemoveHandler = shouldClose || name === 'close';
92
+ if (shouldRemoveHandler) {
93
+ delete dialogHandlers[name];
94
+ }
95
+ }
96
+ if (shouldClose) {
97
+ AP.dialog.close();
98
+ }
99
+ }
100
+
101
+ function registerHandler(event, callback) {
102
+ if (typeof callback === 'function') {
103
+ if (!dialogHandlers[event]) {
104
+ dialogHandlers[event] = [];
105
+ }
106
+ dialogHandlers[event].push(callback);
107
+ }
108
+ }
109
+
110
+ if(AP.dialog && AP.dialog.create) {
111
+ const original_dialogCreate = AP.dialog.create.prototype.constructor.bind({});
112
+
113
+ AP.dialog.create = AP._hostModules.dialog.create = (...args) => {
114
+ const dialog = original_dialogCreate(...args);
115
+ /**
116
+ * Allows the add-on to register a callback function for the given event. The listener is only called once and must be re-registered if needed.
117
+ * @deprecated after August 2017 | Please use <code>AP.events.on("dialog.close", callback)</code> instead.
118
+ * @memberOf Dialog~Dialog
119
+ * @method on
120
+ * @ignore
121
+ * @param {String} event name of the event to listen for, such as 'close'.
122
+ * @param {Function} callback function to receive the event callback.
123
+ * @noDemo
124
+ * @example
125
+ * AP.dialog.create(opts).on("close", callbackFunc);
126
+ */
127
+ dialog.on = deprecate(registerHandler,
128
+ 'AP.dialog.on("close", callback)', 'AP.events.on("dialog.close", callback)', '5.0');
129
+ return dialog;
130
+ };
131
+ }
132
+
133
+ if(AP.dialog && AP.dialog.getButton) {
134
+ let original_dialogGetButton = AP.dialog.getButton.prototype.constructor.bind({});
135
+
136
+ AP.dialog.getButton = AP._hostModules.dialog.getButton = function(name) {
137
+ try {
138
+ const button = original_dialogGetButton(name);
139
+ /**
140
+ * Registers a function to be called when the button is clicked.
141
+ * @deprecated after August 2017 | Please use <code>AP.events.on("dialog.message", callback)</code> instead.
142
+ * @method bind
143
+ * @memberOf Dialog~DialogButton
144
+ * @ignore
145
+ * @param {Function} callback function to be triggered on click or programatically.
146
+ * @noDemo
147
+ * @example
148
+ * AP.dialog.getButton('submit').bind(function(){
149
+ * alert('clicked!');
150
+ * });
151
+ */
152
+ button.bind = deprecate((callback) => registerHandler(name, callback),
153
+ 'AP.dialog.getDialogButton().bind()', 'AP.events.on("dialog.message", callback)', '5.0');
154
+
155
+ return button;
156
+ } catch (e) {
157
+ return {};
158
+ }
159
+ };
160
+ }
161
+
162
+ if(AP.dialog && AP.dialog.createButton) {
163
+ let original_dialogCreateButton = AP.dialog.createButton.prototype.constructor.bind({});
164
+
165
+ AP.dialog.createButton = AP._hostModules.dialog.createButton = function(options) {
166
+ let buttonProperties = {};
167
+ if(typeof options !== 'object') {
168
+ buttonProperties.text = options;
169
+ buttonProperties.identifier = options;
170
+ } else {
171
+ buttonProperties = options;
172
+ }
173
+ if(!buttonProperties.identifier) {
174
+ buttonProperties.identifier = 'user.button.' + customButtonIncrement++;
175
+ }
176
+ let createButton = original_dialogCreateButton(buttonProperties);
177
+ return AP.dialog.getButton(buttonProperties.identifier);
178
+ };
179
+ }
180
+
181
+ /**
182
+ * Register callbacks responding to messages from the host dialog, such as "submit" or "cancel"
183
+ * @deprecated after August 2017 | Please use <code>AP.events.on("dialog.message", callback)</code> instead.
184
+ * @memberOf module:Dialog
185
+ * @method onDialogMessage
186
+ * @ignore
187
+ * @param {String} buttonName - button either "cancel" or "submit"
188
+ * @param {Function} listener - callback function invoked when the requested button is pressed
189
+ */
190
+ if(AP.dialog) {
191
+ AP.dialog.onDialogMessage = AP._hostModules.dialog.onDialogMessage = deprecate(registerHandler,
192
+ 'AP.dialog.onDialogMessage()', 'AP.events.on("dialog.message", callback)', '5.0');
193
+ }
194
+
195
+ if(!AP.Dialog){
196
+ AP.Dialog = AP._hostModules.Dialog = AP.dialog;
197
+ }
@@ -0,0 +1,77 @@
1
+ import util from './util';
2
+
3
+ var each = util.each;
4
+ var extend = util.extend;
5
+ var document = window.document;
6
+
7
+ function $(sel, context) {
8
+
9
+ context = context || document;
10
+
11
+ var els = [];
12
+ if (sel) {
13
+ if (typeof sel === 'string') {
14
+ var results = context.querySelectorAll(sel);
15
+ each(results, function (i, v) {
16
+ els.push(v);
17
+ });
18
+ } else if (sel.nodeType === 1) {
19
+ els.push(sel);
20
+ } else if (sel === window) {
21
+ els.push(sel);
22
+ }
23
+ }
24
+
25
+ extend(els, {
26
+ each: function (it) {
27
+ each(this, it);
28
+ return this;
29
+ },
30
+ bind: function (name, callback) {
31
+ this.each(function (i, el) {
32
+ util.bind(el, name, callback);
33
+ });
34
+ },
35
+ attr: function (k) {
36
+ var v;
37
+ this.each(function (i, el) {
38
+ v = el[k] || (el.getAttribute && el.getAttribute(k));
39
+ return !v;
40
+ });
41
+ return v;
42
+ },
43
+ removeClass: function (className) {
44
+ return this.each(function (i, el) {
45
+ if (el.className) {
46
+ el.className = el.className.replace(new RegExp('(^|\\s)' + className + '(\\s|$)'), ' ');
47
+ }
48
+ });
49
+ },
50
+ html: function (html) {
51
+ return this.each(function (i, el) {
52
+ el.innerHTML = html;
53
+ });
54
+ },
55
+ append: function (spec) {
56
+ return this.each(function (i, to) {
57
+ var el = context.createElement(spec.tag);
58
+ each(spec, function (k, v) {
59
+ if (k === '$text') {
60
+ if (el.styleSheet) { // style tags in ie
61
+ el.styleSheet.cssText = v;
62
+ } else {
63
+ el.appendChild(context.createTextNode(v));
64
+ }
65
+ } else if (k !== 'tag') {
66
+ el[k] = v;
67
+ }
68
+ });
69
+ to.appendChild(el);
70
+ });
71
+ }
72
+ });
73
+
74
+ return els;
75
+ }
76
+
77
+ export default extend($, util);
@@ -0,0 +1,2 @@
1
+ import Events from './events';
2
+ export default new Events();