@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,594 @@
|
|
|
1
|
+
import host from 'simple-xdm/host';
|
|
2
|
+
import plugin from 'simple-xdm/combined';
|
|
3
|
+
import ThemingHost, { ThemingModuleState } from '../../src/host/modules/theming';
|
|
4
|
+
import ThemingPlugin, {
|
|
5
|
+
loadLegacyTextColorStylesCdn,
|
|
6
|
+
} from '../../src/plugin/theming';
|
|
7
|
+
import {
|
|
8
|
+
resetFeatureFlags,
|
|
9
|
+
} from '../mocks/mock_feature_flag';
|
|
10
|
+
|
|
11
|
+
const lightTheme = {
|
|
12
|
+
dark: 'dark',
|
|
13
|
+
light: 'light',
|
|
14
|
+
spacing: 'spacing',
|
|
15
|
+
colorMode: 'light',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const darkTheme = {
|
|
19
|
+
dark: 'dark',
|
|
20
|
+
light: 'light',
|
|
21
|
+
spacing: 'spacing',
|
|
22
|
+
colorMode: 'dark',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function getFakeCallback(extensionId) {
|
|
26
|
+
const fakeCallback = function () {};
|
|
27
|
+
fakeCallback._context = { extension_id: extensionId || 'abc123' };
|
|
28
|
+
|
|
29
|
+
return fakeCallback;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
describe('theming module', () => {
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
document.documentElement.removeAttribute('data-theme');
|
|
35
|
+
document.documentElement.removeAttribute('data-color-mode');
|
|
36
|
+
document.documentElement.removeAttribute('data-surface');
|
|
37
|
+
document.querySelectorAll('link[data-surface]').forEach((e) => e.remove());
|
|
38
|
+
document.querySelectorAll('style[data-theme]').forEach((e) => e.remove());
|
|
39
|
+
document.querySelectorAll('link[data-theme]').forEach((e) => e.remove());
|
|
40
|
+
document.querySelectorAll('#atlassian-connect-dark-mode-fix').forEach((e) => e.remove());
|
|
41
|
+
ThemingModuleState.extensionIds = [];
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
afterEach(() => {
|
|
45
|
+
resetFeatureFlags()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
describe('host', () => {
|
|
49
|
+
it('should fetch theme and broadcast theme_initialized when initializeTheming is called with an extension ID', () => {
|
|
50
|
+
const observerSpy = spyOn(ThemingModuleState.themeObserver, 'observe');
|
|
51
|
+
const spy = spyOn(host, 'broadcast');
|
|
52
|
+
|
|
53
|
+
const fakeCallback = getFakeCallback();
|
|
54
|
+
|
|
55
|
+
document.documentElement.dataset.theme =
|
|
56
|
+
'light:light dark:dark spacing:spacing typography:typography';
|
|
57
|
+
document.documentElement.setAttribute('data-color-mode', 'dark');
|
|
58
|
+
|
|
59
|
+
ThemingHost.initializeTheming(false, fakeCallback);
|
|
60
|
+
|
|
61
|
+
expect(observerSpy).toHaveBeenCalledWith(document.documentElement);
|
|
62
|
+
|
|
63
|
+
const initialTheme = darkTheme;
|
|
64
|
+
|
|
65
|
+
expect(spy).toHaveBeenCalledWith(
|
|
66
|
+
'theme_initialized',
|
|
67
|
+
{ id: fakeCallback._context.extension_id },
|
|
68
|
+
{ initialTheme, forceNoCleanup: false, featureFlags: {}, surface: undefined }
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should fetch theme and broadcast theme_initialized with forceNoCleanup', () => {
|
|
73
|
+
const observerSpy = spyOn(ThemingModuleState.themeObserver, 'observe');
|
|
74
|
+
const spy = spyOn(host, 'broadcast');
|
|
75
|
+
const fakeCallback = getFakeCallback();
|
|
76
|
+
|
|
77
|
+
document.documentElement.dataset.theme =
|
|
78
|
+
'light:light dark:dark spacing:spacing typography:typography';
|
|
79
|
+
document.documentElement.setAttribute('data-color-mode', 'dark');
|
|
80
|
+
|
|
81
|
+
ThemingHost.initializeTheming(true, fakeCallback);
|
|
82
|
+
|
|
83
|
+
expect(observerSpy).toHaveBeenCalledWith(document.documentElement);
|
|
84
|
+
|
|
85
|
+
const initialTheme = darkTheme;
|
|
86
|
+
|
|
87
|
+
expect(spy).toHaveBeenCalledWith(
|
|
88
|
+
'theme_initialized',
|
|
89
|
+
{ id: fakeCallback._context.extension_id },
|
|
90
|
+
{
|
|
91
|
+
initialTheme,
|
|
92
|
+
forceNoCleanup: true,
|
|
93
|
+
surface: undefined,
|
|
94
|
+
featureFlags: {},
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should broadcast theme_initialized when initializeTheming is called more than once', () => {
|
|
100
|
+
const observerSpy = spyOn(ThemingModuleState.themeObserver, 'observe');
|
|
101
|
+
const spy = spyOn(host, 'broadcast');
|
|
102
|
+
|
|
103
|
+
const fakeCallback = getFakeCallback();
|
|
104
|
+
|
|
105
|
+
document.documentElement.dataset.theme =
|
|
106
|
+
'light:light dark:dark spacing:spacing typography:typography';
|
|
107
|
+
document.documentElement.setAttribute('data-color-mode', 'dark');
|
|
108
|
+
|
|
109
|
+
ThemingHost.initializeTheming(fakeCallback);
|
|
110
|
+
ThemingHost.initializeTheming(fakeCallback);
|
|
111
|
+
|
|
112
|
+
// Should only observe once even though initializeTheming was called twice for the same ID
|
|
113
|
+
expect(observerSpy).toHaveBeenCalledTimes(1);
|
|
114
|
+
// Should only add the ID to the array once
|
|
115
|
+
expect(ThemingModuleState.extensionIds.length).toBe(1);
|
|
116
|
+
// Should still broadcast the event twice
|
|
117
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should NOT broadcast theme_changed when the theme changes in the host if no extension has enabled theming', (done) => {
|
|
121
|
+
document.documentElement.dataset.theme =
|
|
122
|
+
'light:light dark:dark spacing:spacing typography:typography';
|
|
123
|
+
document.documentElement.setAttribute('data-color-mode', 'light');
|
|
124
|
+
|
|
125
|
+
const spy = spyOn(host, 'broadcast');
|
|
126
|
+
|
|
127
|
+
document.documentElement.dataset.theme =
|
|
128
|
+
'light:light dark:dark spacing:spacing typography:typography';
|
|
129
|
+
document.documentElement.setAttribute('data-color-mode', 'dark');
|
|
130
|
+
|
|
131
|
+
setTimeout(() => {
|
|
132
|
+
expect(spy).not.toHaveBeenCalled();
|
|
133
|
+
done();
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('should broadcast theme_changed when the theme changes in the host and an extension has enabled theming', (done) => {
|
|
138
|
+
const fakeCallback = getFakeCallback();
|
|
139
|
+
|
|
140
|
+
document.documentElement.dataset.theme =
|
|
141
|
+
'light:light dark:dark spacing:spacing typography:typography';
|
|
142
|
+
document.documentElement.setAttribute('data-color-mode', 'light');
|
|
143
|
+
|
|
144
|
+
ThemingHost.initializeTheming(fakeCallback);
|
|
145
|
+
|
|
146
|
+
const spy = spyOn(host, 'broadcast');
|
|
147
|
+
|
|
148
|
+
document.documentElement.dataset.theme =
|
|
149
|
+
'light:light dark:dark spacing:spacing typography:typography';
|
|
150
|
+
document.documentElement.setAttribute('data-color-mode', 'dark');
|
|
151
|
+
|
|
152
|
+
const newTheme = darkTheme;
|
|
153
|
+
|
|
154
|
+
setTimeout(() => {
|
|
155
|
+
expect(spy).toHaveBeenCalledWith(
|
|
156
|
+
'theme_changed',
|
|
157
|
+
{ id: fakeCallback._context.extension_id },
|
|
158
|
+
{
|
|
159
|
+
newTheme,
|
|
160
|
+
featureFlags: {},
|
|
161
|
+
surface: undefined,
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
done();
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should broadcast theme_changed to all extensions that have enabled theming', (done) => {
|
|
169
|
+
const fakeCallback1 = getFakeCallback();
|
|
170
|
+
const fakeCallback2 = getFakeCallback('def456');
|
|
171
|
+
|
|
172
|
+
document.documentElement.dataset.theme =
|
|
173
|
+
'light:light dark:dark spacing:spacing typography:typography';
|
|
174
|
+
document.documentElement.setAttribute('data-color-mode', 'light');
|
|
175
|
+
|
|
176
|
+
ThemingHost.initializeTheming(fakeCallback1);
|
|
177
|
+
ThemingHost.initializeTheming(fakeCallback2);
|
|
178
|
+
|
|
179
|
+
const spy = spyOn(host, 'broadcast');
|
|
180
|
+
|
|
181
|
+
document.documentElement.dataset.theme =
|
|
182
|
+
'light:light dark:dark spacing:spacing typography:typography';
|
|
183
|
+
document.documentElement.setAttribute('data-color-mode', 'dark');
|
|
184
|
+
|
|
185
|
+
const newTheme = darkTheme;
|
|
186
|
+
|
|
187
|
+
setTimeout(() => {
|
|
188
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
|
189
|
+
expect(spy).toHaveBeenCalledWith(
|
|
190
|
+
'theme_changed',
|
|
191
|
+
{ id: fakeCallback1._context.extension_id },
|
|
192
|
+
{
|
|
193
|
+
newTheme,
|
|
194
|
+
featureFlags: {},
|
|
195
|
+
surface: undefined,
|
|
196
|
+
}
|
|
197
|
+
);
|
|
198
|
+
expect(spy).toHaveBeenCalledWith(
|
|
199
|
+
'theme_changed',
|
|
200
|
+
{ id: fakeCallback2._context.extension_id },
|
|
201
|
+
{
|
|
202
|
+
newTheme,
|
|
203
|
+
featureFlags: {},
|
|
204
|
+
surface: undefined,
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
done();
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
describe('plugin', () => {
|
|
213
|
+
beforeEach(() => {
|
|
214
|
+
plugin.theming = ThemingHost;
|
|
215
|
+
ThemingPlugin.isThemingEnabled = false;
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('should register event listeners when initializeThemeListeners is called', () => {
|
|
219
|
+
const spy = spyOn(plugin, 'register');
|
|
220
|
+
|
|
221
|
+
ThemingPlugin.initializeThemeListeners();
|
|
222
|
+
|
|
223
|
+
expect(spy).toHaveBeenCalledWith({
|
|
224
|
+
theme_initialized: ThemingPlugin.onThemeInitialized,
|
|
225
|
+
theme_changed: ThemingPlugin.onThemeChanged,
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('should NOT register event listeners when initializeThemeListeners is called if theming is disabled', () => {
|
|
230
|
+
plugin.theming = undefined;
|
|
231
|
+
const spy = spyOn(plugin, 'register');
|
|
232
|
+
|
|
233
|
+
ThemingPlugin.initializeThemeListeners();
|
|
234
|
+
|
|
235
|
+
expect(spy).not.toHaveBeenCalled();
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it('should set the initial theme when theming is initialized', async (done) => {
|
|
239
|
+
const initialTheme = lightTheme;
|
|
240
|
+
|
|
241
|
+
await ThemingPlugin.onThemeInitialized({ initialTheme });
|
|
242
|
+
|
|
243
|
+
expect(document.documentElement.dataset.theme).toBe(
|
|
244
|
+
'dark:dark light:light spacing:spacing'
|
|
245
|
+
);
|
|
246
|
+
expect(document.documentElement.getAttribute('data-color-mode')).toBe(
|
|
247
|
+
'light'
|
|
248
|
+
);
|
|
249
|
+
done();
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it('should set the new theme in the DOM when theme changes and theming is initialized', async (done) => {
|
|
253
|
+
const initialTheme = lightTheme;
|
|
254
|
+
|
|
255
|
+
await ThemingPlugin.onThemeInitialized({ initialTheme });
|
|
256
|
+
|
|
257
|
+
expect(document.documentElement.dataset.theme).toBe(
|
|
258
|
+
'dark:dark light:light spacing:spacing'
|
|
259
|
+
);
|
|
260
|
+
expect(document.documentElement.getAttribute('data-color-mode')).toBe(
|
|
261
|
+
'light'
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
const newTheme = darkTheme;
|
|
265
|
+
|
|
266
|
+
await ThemingPlugin.onThemeChanged({ newTheme });
|
|
267
|
+
|
|
268
|
+
expect(document.documentElement.dataset.theme).toBe(
|
|
269
|
+
'dark:dark light:light spacing:spacing'
|
|
270
|
+
);
|
|
271
|
+
expect(document.documentElement.getAttribute('data-color-mode')).toBe(
|
|
272
|
+
'dark'
|
|
273
|
+
);
|
|
274
|
+
done();
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('should remove themes on the DOM when theming is disabled', async (done) => {
|
|
278
|
+
const initialTheme = lightTheme;
|
|
279
|
+
|
|
280
|
+
await ThemingPlugin.onThemeInitialized({ initialTheme });
|
|
281
|
+
|
|
282
|
+
expect(document.documentElement.dataset.theme).toBe(
|
|
283
|
+
'dark:dark light:light spacing:spacing'
|
|
284
|
+
);
|
|
285
|
+
expect(document.documentElement.getAttribute('data-color-mode')).toBe(
|
|
286
|
+
'light'
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
const newTheme = {};
|
|
290
|
+
|
|
291
|
+
await ThemingPlugin.onThemeChanged({ newTheme });
|
|
292
|
+
|
|
293
|
+
expect(document.documentElement.hasAttribute('data-theme')).toBe(false);
|
|
294
|
+
expect(document.documentElement.hasAttribute('data-color-mode')).toBe(
|
|
295
|
+
false
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
done();
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it('should not set up themes when initializeTheming is called but the host has theming disabled', async (done) => {
|
|
302
|
+
const initialTheme = {};
|
|
303
|
+
|
|
304
|
+
await ThemingPlugin.onThemeInitialized({ initialTheme });
|
|
305
|
+
|
|
306
|
+
expect(document.documentElement.hasAttribute('data-theme')).toBe(false);
|
|
307
|
+
expect(document.documentElement.hasAttribute('data-color-mode')).toBe(
|
|
308
|
+
false
|
|
309
|
+
);
|
|
310
|
+
done();
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('should NOT set the new theme in the DOM when theme changes and theming is NOT initialized', async (done) => {
|
|
314
|
+
const newTheme = darkTheme;
|
|
315
|
+
|
|
316
|
+
await ThemingPlugin.onThemeChanged({ newTheme });
|
|
317
|
+
|
|
318
|
+
expect(document.documentElement.dataset.theme).toBeUndefined();
|
|
319
|
+
expect(
|
|
320
|
+
document.documentElement.getAttribute('data-color-mode')
|
|
321
|
+
).toBeNull();
|
|
322
|
+
done();
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
describe('Force no clean-up', () => {
|
|
326
|
+
it('should set default themes on the DOM when theming is disabled by default', async (done) => {
|
|
327
|
+
const initialTheme = {};
|
|
328
|
+
|
|
329
|
+
await ThemingPlugin.onThemeInitialized({ initialTheme, forceNoCleanup: true });
|
|
330
|
+
|
|
331
|
+
expect(document.documentElement.dataset.theme).toBe(
|
|
332
|
+
'dark:dark light:light spacing:spacing'
|
|
333
|
+
);
|
|
334
|
+
expect(document.documentElement.getAttribute('data-color-mode')).toBe(
|
|
335
|
+
'light'
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
done();
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it('should set default themes on the DOM when theming is disabled', async (done) => {
|
|
342
|
+
const initialTheme = lightTheme;
|
|
343
|
+
|
|
344
|
+
await ThemingPlugin.onThemeInitialized({
|
|
345
|
+
initialTheme,
|
|
346
|
+
forceNoCleanup: true,
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
expect(document.documentElement.dataset.theme).toBe(
|
|
350
|
+
'dark:dark light:light spacing:spacing'
|
|
351
|
+
);
|
|
352
|
+
expect(document.documentElement.getAttribute('data-color-mode')).toBe(
|
|
353
|
+
'light'
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
const newTheme = {};
|
|
357
|
+
|
|
358
|
+
await ThemingPlugin.onThemeChanged({ newTheme });
|
|
359
|
+
|
|
360
|
+
expect(document.documentElement.dataset.theme).toBe(
|
|
361
|
+
'dark:dark light:light spacing:spacing'
|
|
362
|
+
);
|
|
363
|
+
expect(document.documentElement.getAttribute('data-color-mode')).toBe(
|
|
364
|
+
'light'
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
done();
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
describe('should load stylesheets from the Connect CDN', () => {
|
|
372
|
+
it('should set default themes on the DOM', async (done) => {
|
|
373
|
+
const initialTheme = lightTheme;
|
|
374
|
+
|
|
375
|
+
await ThemingPlugin.onThemeInitialized({
|
|
376
|
+
initialTheme,
|
|
377
|
+
featureFlags: {},
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
expect(
|
|
381
|
+
document.querySelectorAll('link[data-theme="light"]').length
|
|
382
|
+
).toEqual(1);
|
|
383
|
+
expect(document.documentElement.dataset.theme).toBe(
|
|
384
|
+
'dark:dark light:light spacing:spacing'
|
|
385
|
+
);
|
|
386
|
+
expect(document.documentElement.getAttribute('data-color-mode')).toBe(
|
|
387
|
+
'light'
|
|
388
|
+
);
|
|
389
|
+
|
|
390
|
+
done();
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
it('should handle theme changes from the parent app', async (done) => {
|
|
394
|
+
const initialTheme = lightTheme;
|
|
395
|
+
|
|
396
|
+
await ThemingPlugin.onThemeInitialized({
|
|
397
|
+
initialTheme,
|
|
398
|
+
featureFlags: {},
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
expect(
|
|
402
|
+
document.querySelectorAll('link[data-theme="light"]').length
|
|
403
|
+
).toEqual(1);
|
|
404
|
+
expect(document.documentElement.dataset.theme).toBe(
|
|
405
|
+
'dark:dark light:light spacing:spacing'
|
|
406
|
+
);
|
|
407
|
+
expect(document.documentElement.getAttribute('data-color-mode')).toBe(
|
|
408
|
+
'light'
|
|
409
|
+
);
|
|
410
|
+
|
|
411
|
+
const newTheme = darkTheme;
|
|
412
|
+
|
|
413
|
+
await ThemingPlugin.onThemeChanged({
|
|
414
|
+
newTheme,
|
|
415
|
+
featureFlags: {},
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
expect(
|
|
419
|
+
document.querySelectorAll('link[data-theme="dark"]').length
|
|
420
|
+
).toEqual(1);
|
|
421
|
+
expect(document.documentElement.dataset.theme).toBe(
|
|
422
|
+
'dark:dark light:light spacing:spacing'
|
|
423
|
+
);
|
|
424
|
+
expect(document.documentElement.getAttribute('data-color-mode')).toBe(
|
|
425
|
+
'dark'
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
done();
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
it('should clean up themes when parent app disables theming', async (done) => {
|
|
432
|
+
const initialTheme = lightTheme;
|
|
433
|
+
|
|
434
|
+
await ThemingPlugin.onThemeInitialized({
|
|
435
|
+
initialTheme,
|
|
436
|
+
featureFlags: {},
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
expect(
|
|
440
|
+
document.querySelectorAll('link[data-theme="light"]').length
|
|
441
|
+
).toEqual(1);
|
|
442
|
+
expect(document.documentElement.dataset.theme).toBe(
|
|
443
|
+
'dark:dark light:light spacing:spacing'
|
|
444
|
+
);
|
|
445
|
+
expect(document.documentElement.getAttribute('data-color-mode')).toBe(
|
|
446
|
+
'light'
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
const newTheme = {};
|
|
450
|
+
|
|
451
|
+
await ThemingPlugin.onThemeChanged({
|
|
452
|
+
newTheme,
|
|
453
|
+
featureFlags: {},
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
expect(document.documentElement.dataset.theme).toBeUndefined();
|
|
457
|
+
expect(
|
|
458
|
+
document.documentElement.getAttribute('data-color-mode')
|
|
459
|
+
).toBeNull();
|
|
460
|
+
|
|
461
|
+
done();
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
describe('Surface detection', () => {
|
|
466
|
+
it('should apply supplied surface level', async (done) => {
|
|
467
|
+
await ThemingPlugin.onThemeInitialized({
|
|
468
|
+
initialTheme: lightTheme,
|
|
469
|
+
surface: 'raised',
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
expect(document.querySelector('link[data-surface]')).not.toBeFalsy();
|
|
473
|
+
expect(document.documentElement.getAttribute('data-surface')).toContain('raised');
|
|
474
|
+
done();
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
it('should remove surface level attr when forceNoCleanup is true (but keep styles)', async (done) => {
|
|
478
|
+
await ThemingPlugin.onThemeInitialized({
|
|
479
|
+
initialTheme: undefined,
|
|
480
|
+
surface: undefined,
|
|
481
|
+
forceNoCleanup: true,
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
expect(document.documentElement.getAttribute('data-surface')).toBeNull();
|
|
485
|
+
done();
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
it('should remove surface level on clean up', async (done) => {
|
|
489
|
+
await ThemingPlugin.onThemeInitialized({
|
|
490
|
+
initialTheme: lightTheme,
|
|
491
|
+
surface: 'raised',
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
expect(document.querySelector('link[data-surface]')).not.toBeFalsy();
|
|
495
|
+
expect(document.documentElement.getAttribute('data-surface')).toContain('raised');
|
|
496
|
+
|
|
497
|
+
await ThemingPlugin.onThemeChanged({
|
|
498
|
+
newTheme: undefined,
|
|
499
|
+
surface: undefined,
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
expect(document.documentElement.getAttribute('data-surface')).toBeNull();
|
|
503
|
+
|
|
504
|
+
done();
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it('should not apply supplied surface level if omitted', async (done) => {
|
|
508
|
+
await ThemingPlugin.onThemeInitialized({ initialTheme: lightTheme });
|
|
509
|
+
|
|
510
|
+
expect(
|
|
511
|
+
document.documentElement.getAttribute('data-surface')
|
|
512
|
+
).toBeNull();
|
|
513
|
+
expect(document.querySelector('link[data-surface]')).toBeNull();
|
|
514
|
+
done();
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
it('should not apply supplied surface level if undefined', async (done) => {
|
|
518
|
+
await ThemingPlugin.onThemeInitialized({
|
|
519
|
+
initialTheme: lightTheme,
|
|
520
|
+
surface: undefined,
|
|
521
|
+
});
|
|
522
|
+
expect(
|
|
523
|
+
document.documentElement.getAttribute('data-surface')
|
|
524
|
+
).toBeNull();
|
|
525
|
+
expect(document.querySelector('link[data-surface]')).toBeNull();
|
|
526
|
+
done();
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
it('should apply supplied surface level on theme change', async (done) => {
|
|
530
|
+
await ThemingPlugin.onThemeInitialized({
|
|
531
|
+
initialTheme: lightTheme,
|
|
532
|
+
surface: undefined,
|
|
533
|
+
});
|
|
534
|
+
expect(
|
|
535
|
+
document.documentElement.getAttribute('data-surface')
|
|
536
|
+
).toBeNull();
|
|
537
|
+
expect(document.querySelector('link[data-surface]')).toBeNull();
|
|
538
|
+
|
|
539
|
+
await ThemingPlugin.onThemeChanged({
|
|
540
|
+
newTheme: darkTheme,
|
|
541
|
+
surface: 'overlay',
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
expect(document.querySelector('link[data-surface]')).not.toBeFalsy();
|
|
545
|
+
expect(document.documentElement.getAttribute('data-surface')).toContain('overlay');
|
|
546
|
+
|
|
547
|
+
done();
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
it('should apply supplied surface level on theme change', async (done) => {
|
|
551
|
+
await ThemingPlugin.onThemeInitialized({
|
|
552
|
+
initialTheme: lightTheme,
|
|
553
|
+
surface: 'raised',
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
expect(document.querySelector('link[data-surface]')).not.toBeFalsy();
|
|
557
|
+
expect(document.documentElement.getAttribute('data-surface')).toContain('raised');
|
|
558
|
+
|
|
559
|
+
await ThemingPlugin.onThemeChanged({
|
|
560
|
+
newTheme: darkTheme,
|
|
561
|
+
surface: 'overlay',
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
expect(document.documentElement.getAttribute('data-surface')).toContain('overlay');
|
|
565
|
+
|
|
566
|
+
done();
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
it('should remove surface level when theming is disabled', async (done) => {
|
|
570
|
+
await ThemingPlugin.onThemeInitialized({
|
|
571
|
+
initialTheme: lightTheme,
|
|
572
|
+
surface: 'overlay',
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
expect(document.querySelector('link[data-surface]')).not.toBeFalsy();
|
|
576
|
+
expect(document.documentElement.getAttribute('data-surface')).toContain('overlay');
|
|
577
|
+
|
|
578
|
+
await ThemingPlugin.onThemeChanged({ newTheme: darkTheme });
|
|
579
|
+
|
|
580
|
+
expect(document.documentElement.getAttribute('data-surface')).toBeNull();
|
|
581
|
+
|
|
582
|
+
done();
|
|
583
|
+
});
|
|
584
|
+
});
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
describe('legacy text colors', () => {
|
|
588
|
+
it('should append legacy text colors styles tag', async (done) => {
|
|
589
|
+
await loadLegacyTextColorStylesCdn()
|
|
590
|
+
expect(document.querySelector('link[data-legacy-text-colors]')).toBeTruthy()
|
|
591
|
+
done()
|
|
592
|
+
});
|
|
593
|
+
})
|
|
594
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import Util from 'src/host/util';
|
|
2
|
+
|
|
3
|
+
describe('Host utils', () => {
|
|
4
|
+
describe('last', () => {
|
|
5
|
+
|
|
6
|
+
it('returns the last entry in an array', () => {
|
|
7
|
+
var arr = ['a','b','c','d'];
|
|
8
|
+
expect(Util.last(arr)).toEqual('d');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
});
|
|
12
|
+
describe('first', () => {
|
|
13
|
+
|
|
14
|
+
it('returns the first entry in an array', () => {
|
|
15
|
+
var arr = ['a','b','c','d'];
|
|
16
|
+
expect(Util.first(arr)).toEqual('a');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('returns the first X entries in an array', () => {
|
|
20
|
+
var arr = ['a','b','c','d'];
|
|
21
|
+
expect(Util.first(arr, 3)).toEqual(['a','b','c']);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe('pick', () => {
|
|
27
|
+
|
|
28
|
+
it('returns a filtered copy of obj with only the specified keys', () => {
|
|
29
|
+
var obj = {
|
|
30
|
+
a: 'aaa',
|
|
31
|
+
b: 'bb',
|
|
32
|
+
c: 'cccc',
|
|
33
|
+
d: ['a','b','c']
|
|
34
|
+
};
|
|
35
|
+
expect(Util.pick(obj, ['b','d'])).toEqual({
|
|
36
|
+
b: 'bb', d: ['a','b','c']
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('returns an empty object when nothing matches', () => {
|
|
42
|
+
var obj = {
|
|
43
|
+
a: 'aaa',
|
|
44
|
+
b: 'bb',
|
|
45
|
+
c: 'cccc',
|
|
46
|
+
d: ['a','b','c']
|
|
47
|
+
};
|
|
48
|
+
expect(Util.pick(obj, ['x'])).toEqual({});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('returns an empty object when undefined is supplied', () => {
|
|
52
|
+
expect(Util.pick(undefined, ['x'])).toEqual({});
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Base64 from 'src/host/utils/base64';
|
|
2
|
+
|
|
3
|
+
describe('base64 util', () => {
|
|
4
|
+
const testString = 'somestring';
|
|
5
|
+
const testStringEncoded = 'c29tZXN0cmluZw==';
|
|
6
|
+
|
|
7
|
+
describe('encode', () => {
|
|
8
|
+
it('encodes given string', () => {
|
|
9
|
+
expect(Base64.encode(testString)).toEqual(testStringEncoded);
|
|
10
|
+
})
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe('decode', () => {
|
|
14
|
+
it('decodes encoded string', () => {
|
|
15
|
+
const encoded = Base64.encode(testString);
|
|
16
|
+
expect(encoded).toEqual(testStringEncoded);
|
|
17
|
+
expect(Base64.decode(encoded)).toEqual(testString);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import ButtonUtils from 'src/host/utils/button';
|
|
2
|
+
|
|
3
|
+
describe('button utils', () => {
|
|
4
|
+
describe('randomIdentifier', () => {
|
|
5
|
+
it('returns random id', () => {
|
|
6
|
+
var randomId1 = ButtonUtils.randomIdentifier();
|
|
7
|
+
var randomId2 = ButtonUtils.randomIdentifier();
|
|
8
|
+
expect(randomId1).not.toEqual(randomId2);
|
|
9
|
+
});
|
|
10
|
+
})
|
|
11
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Cookie from 'src/host/utils/cookie';
|
|
2
|
+
|
|
3
|
+
describe('cookie util', () => {
|
|
4
|
+
describe('prefixCookie', () => {
|
|
5
|
+
it('returns expected result', () => {
|
|
6
|
+
const addonKey = 'someAddonKey';
|
|
7
|
+
const name = 'cookieName';
|
|
8
|
+
expect(Cookie.prefixCookie(addonKey, name)).toEqual(`${addonKey}$$${name}`);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('throws an error if addonKey is missing', () => {
|
|
12
|
+
expect(() => Cookie.prefixCookie(null, 'name')).toThrow(new Error('addon key must be defined on cookies'));
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('throws an error if name is missing', () => {
|
|
16
|
+
expect(() => Cookie.prefixCookie('key', null)).toThrow(new Error('Name must be defined'));
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
});
|