@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.
- package/.depcheckrc.json +16 -0
- package/.editorconfig +9 -0
- package/.envrc +5 -0
- package/.eslintignore +12 -0
- package/.eslintrc +31 -0
- package/.husky/pre-commit +11 -0
- package/.lintstagedrc.js +6 -0
- package/.netrc +1 -0
- package/.npmrc-public +4 -0
- package/.nvmrc +1 -0
- package/LICENSE +3 -0
- package/README.md +281 -0
- package/bitbucket-pipelines.yml +33 -0
- package/build/bin/bin-helper.js +29 -0
- package/build/bin/npm-postinstall.js +9 -0
- package/build/configs/append-sourcemapping.js +13 -0
- package/build/configs/availabletasks.js +15 -0
- package/build/configs/clean.js +12 -0
- package/build/configs/concat.js +44 -0
- package/build/configs/copy.js +32 -0
- package/build/configs/index.js +19 -0
- package/build/configs/jshint.js +9 -0
- package/build/configs/karma.js +11 -0
- package/build/configs/replace.js +10 -0
- package/build/configs/requirejs.js +187 -0
- package/build/configs/saucelabs-launchers.js +30 -0
- package/build/configs/shell.js +24 -0
- package/build/configs/uglify.js +15 -0
- package/build/configs/watch.js +45 -0
- package/build/end.frag +13 -0
- package/build/start.frag +18 -0
- package/bundlesize.config.json +14 -0
- package/dist/connect-host.css +225 -0
- package/dist/connect-host.js +13908 -0
- package/dist/connect-host.min.css +1 -0
- package/dist/iframe-fedramp.js +13663 -0
- package/dist/iframe.js +13663 -0
- package/dist/legacy-text-colors.css +245 -0
- package/dist/surfaces.css +11 -0
- package/dist/themes/atlaskit-tokens_dark-future.css +6 -0
- package/dist/themes/atlaskit-tokens_dark.css +394 -0
- package/dist/themes/atlaskit-tokens_legacy-dark.css +394 -0
- package/dist/themes/atlaskit-tokens_legacy-light.css +394 -0
- package/dist/themes/atlaskit-tokens_light-future.css +6 -0
- package/dist/themes/atlaskit-tokens_light.css +394 -0
- package/dist/themes/atlaskit-tokens_shape.css +14 -0
- package/dist/themes/atlaskit-tokens_spacing.css +26 -0
- package/dist/themes/atlaskit-tokens_typography-adg3.css +25 -0
- package/dist/themes/atlaskit-tokens_typography-modernized.css +25 -0
- package/dist/themes/atlaskit-tokens_typography-refreshed.css +25 -0
- package/gulpfile.js +204 -0
- package/memleak-check/app.html +10 -0
- package/memleak-check/index.html +31 -0
- package/memleak-check/index.js +33 -0
- package/package.json +102 -0
- package/renovate.json +11 -0
- package/security-assistant.yml +2 -0
- package/spec/.eslintrc +10 -0
- package/spec/config/karma.base.conf.js +200 -0
- package/spec/config/karma.conf.js +20 -0
- package/spec/fixtures/base_dialog_component_tests.js +180 -0
- package/spec/mocks/mock_feature_flag.js +23 -0
- package/spec/tests/amd_spec.js +122 -0
- package/spec/tests/analytics_dispatcher_spec.js +429 -0
- package/spec/tests/analytics_performance_spec.js +41 -0
- package/spec/tests/button_spec.js +143 -0
- package/spec/tests/dialog_extension_spec.js +59 -0
- package/spec/tests/dialog_module_provider_spec.js +499 -0
- package/spec/tests/dialog_module_spec.js +395 -0
- package/spec/tests/dialog_spec.js +296 -0
- package/spec/tests/dialog_webitem_spec.js +183 -0
- package/spec/tests/dropdown_module_spec.js +77 -0
- package/spec/tests/env_module_spec.js +153 -0
- package/spec/tests/events_spec.js +77 -0
- package/spec/tests/extension_configuration_options_store_spec.js +25 -0
- package/spec/tests/flag_module_provider_spec.js +79 -0
- package/spec/tests/flag_module_spec.js +118 -0
- package/spec/tests/flag_spec.js +243 -0
- package/spec/tests/host-api_spec.js +220 -0
- package/spec/tests/iframe-create_spec.js +43 -0
- package/spec/tests/iframe_container_spec.js +19 -0
- package/spec/tests/iframe_spec.js +265 -0
- package/spec/tests/inline_dialog_spec.js +41 -0
- package/spec/tests/inline_dialog_webitem_spec.js +331 -0
- package/spec/tests/loading_indicator_spec.js +48 -0
- package/spec/tests/messages_module_spec.js +108 -0
- package/spec/tests/meta_spec.js +71 -0
- package/spec/tests/module_args_spec.js +52 -0
- package/spec/tests/observe_spec.js +73 -0
- package/spec/tests/public_events.spec.js +102 -0
- package/spec/tests/scroll_position_spec.js +109 -0
- package/spec/tests/theming_spec.js +594 -0
- package/spec/tests/util_spec.js +55 -0
- package/spec/tests/utils/base64_spec.js +20 -0
- package/spec/tests/utils/button_spec.js +11 -0
- package/spec/tests/utils/cookie_spec.js +19 -0
- package/spec/tests/utils/deprecate_spec.js +22 -0
- package/spec/tests/utils/dialog_spec.js +297 -0
- package/spec/tests/utils/host_util_spec.js +45 -0
- package/spec/tests/utils/iframe_spec.js +41 -0
- package/spec/tests/utils/jwt_spec.js +135 -0
- package/spec/tests/utils/url_spec.js +37 -0
- package/spec/tests/utils/waitUntilReadyNextTick.js +5 -0
- package/spec/tests/utils/webitem.js +219 -0
- package/spec/tests/webitem_spec.js +131 -0
- package/src/css/host/dialog.css +144 -0
- package/src/css/host/flags.css +5 -0
- package/src/css/host/host.css +64 -0
- package/src/css/host/messages.css +12 -0
- package/src/css/plugin/legacy-text-colors.less +55 -0
- package/src/css/plugin/surfaces.css +11 -0
- package/src/host/ACJSFrameworkAdaptor.js +44 -0
- package/src/host/actions/analytics_action.js +35 -0
- package/src/host/actions/button_actions.js +21 -0
- package/src/host/actions/dialog_actions.js +27 -0
- package/src/host/actions/dialog_extension_actions.js +25 -0
- package/src/host/actions/dom_event_actions.js +32 -0
- package/src/host/actions/dropdown_actions.js +12 -0
- package/src/host/actions/env_actions.js +57 -0
- package/src/host/actions/event_actions.js +33 -0
- package/src/host/actions/flag_actions.js +22 -0
- package/src/host/actions/iframe_actions.js +27 -0
- package/src/host/actions/inline_dialog_actions.js +26 -0
- package/src/host/actions/inline_dialog_webitem_actions.js +10 -0
- package/src/host/actions/jwt_actions.js +51 -0
- package/src/host/actions/loading_indicator_actions.js +10 -0
- package/src/host/actions/module_actions.js +14 -0
- package/src/host/actions/webitem_actions.js +29 -0
- package/src/host/components/button.js +112 -0
- package/src/host/components/dialog.js +447 -0
- package/src/host/components/dialog_extension.js +106 -0
- package/src/host/components/dialog_webitem.js +69 -0
- package/src/host/components/flag.js +102 -0
- package/src/host/components/iframe.js +130 -0
- package/src/host/components/iframe_container.js +38 -0
- package/src/host/components/inline_dialog.js +108 -0
- package/src/host/components/inline_dialog_webitem.js +157 -0
- package/src/host/components/loading_indicator.js +110 -0
- package/src/host/components/webitem.js +227 -0
- package/src/host/deprecate.js +20 -0
- package/src/host/dispatchers/analytics_dispatcher.js +512 -0
- package/src/host/dispatchers/event_dispatcher.js +46 -0
- package/src/host/dollar.js +8 -0
- package/src/host/host-api.js +325 -0
- package/src/host/iframe-create.js +7 -0
- package/src/host/index.js +108 -0
- package/src/host/module-providers.js +13 -0
- package/src/host/modules/_featureFlag.js +42 -0
- package/src/host/modules/_performance.js +54 -0
- package/src/host/modules/analytics.js +17 -0
- package/src/host/modules/dialog.js +496 -0
- package/src/host/modules/dropdown.js +255 -0
- package/src/host/modules/env.js +156 -0
- package/src/host/modules/events.js +28 -0
- package/src/host/modules/flag.js +170 -0
- package/src/host/modules/host.js +19 -0
- package/src/host/modules/inline-dialog.js +33 -0
- package/src/host/modules/messages.js +309 -0
- package/src/host/modules/page.js +29 -0
- package/src/host/modules/scroll-position.js +102 -0
- package/src/host/modules/theming.js +114 -0
- package/src/host/stores/extension_configuration_options_store.js +24 -0
- package/src/host/util.js +98 -0
- package/src/host/utils/access-narrowing-context.js +18 -0
- package/src/host/utils/base64.js +22 -0
- package/src/host/utils/button.js +10 -0
- package/src/host/utils/cookie.js +14 -0
- package/src/host/utils/dialog.js +239 -0
- package/src/host/utils/feature-flag.js +27 -0
- package/src/host/utils/iframe.js +23 -0
- package/src/host/utils/jwt.js +60 -0
- package/src/host/utils/observe.js +34 -0
- package/src/host/utils/removal-observer.js +30 -0
- package/src/host/utils/simplexdm.js +58 -0
- package/src/host/utils/url.js +23 -0
- package/src/host/utils/webitem.js +214 -0
- package/src/plugin/amd.js +115 -0
- package/src/plugin/analytics.js +84 -0
- package/src/plugin/deprecate.js +16 -0
- package/src/plugin/dialog.js +197 -0
- package/src/plugin/dollar.js +77 -0
- package/src/plugin/events-instance.js +2 -0
- package/src/plugin/events.js +246 -0
- package/src/plugin/extension_configuration_options_store.js +27 -0
- package/src/plugin/featureFlag.js +8 -0
- package/src/plugin/index.js +118 -0
- package/src/plugin/meta.js +14 -0
- package/src/plugin/public-events.js +73 -0
- package/src/plugin/theming.js +211 -0
- 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);
|