@shopgate/pwa-common 7.30.0-alpha.7 → 7.30.0-alpha.8
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/App.js +48 -6
- package/action-creators/app/index.js +75 -12
- package/action-creators/app/spec.js +96 -1
- package/action-creators/client/index.js +27 -5
- package/action-creators/client/spec.js +44 -1
- package/action-creators/error/index.js +15 -3
- package/action-creators/index.js +9 -1
- package/action-creators/menu/index.js +23 -4
- package/action-creators/menu/spec.js +37 -1
- package/action-creators/modal/index.js +15 -3
- package/action-creators/modal/spec.js +26 -1
- package/action-creators/page/index.js +24 -4
- package/action-creators/page/spec.js +38 -1
- package/action-creators/router/index.js +48 -7
- package/action-creators/url/index.js +24 -4
- package/action-creators/url/spec.js +45 -1
- package/action-creators/user/index.js +90 -13
- package/action-creators/user/spec.js +186 -2
- package/actions/app/handleDeepLink.js +11 -2
- package/actions/app/handleLink.js +62 -6
- package/actions/app/handlePushNotification.js +32 -4
- package/actions/app/handleUniversalLink.js +11 -2
- package/actions/app/registerLinkEvents.js +24 -3
- package/actions/client/fetchClientInformation.js +26 -2
- package/actions/menu/fetchMenu.js +23 -2
- package/actions/modal/closeModal.js +18 -2
- package/actions/modal/promiseMap.js +3 -1
- package/actions/modal/showModal.js +54 -8
- package/actions/page/fetchPageConfig.js +69 -2
- package/actions/page/getPageConfig.js +6 -2
- package/actions/page/index.js +1 -1
- package/actions/router/historyPop.js +12 -2
- package/actions/router/historyPopToRoute.js +27 -2
- package/actions/router/historyPush.js +12 -2
- package/actions/router/historyRedirect.js +21 -2
- package/actions/router/historyReplace.js +20 -3
- package/actions/router/historyReset.js +11 -2
- package/actions/router/historyResetTo.js +12 -2
- package/actions/router/index.js +17 -1
- package/actions/router/routeDidPop.js +11 -2
- package/actions/router/routeDidPush.js +13 -2
- package/actions/router/routeDidReplace.js +11 -2
- package/actions/router/routeDidReset.js +11 -2
- package/actions/router/routeDidUpdate.js +10 -2
- package/actions/router/routeWillPop.js +11 -2
- package/actions/router/routeWillPush.js +13 -2
- package/actions/router/routeWillReplace.js +11 -2
- package/actions/router/routeWillReset.js +11 -2
- package/actions/router/windowOpenOverride.js +10 -2
- package/actions/user/fetchRegisterUrl.js +36 -2
- package/actions/user/fetchUser.js +29 -3
- package/actions/user/getUser.js +6 -2
- package/actions/user/index.js +1 -1
- package/actions/user/login.js +76 -9
- package/actions/user/logout.js +30 -2
- package/collections/AuthRoutes.js +73 -14
- package/collections/Configuration.js +54 -7
- package/collections/EmbeddedMedia.js +84 -11
- package/collections/PersistedReducers.js +41 -6
- package/collections/Redirects.js +103 -17
- package/collections/index.js +5 -1
- package/collections/media-providers/MediaProvider.js +151 -26
- package/collections/media-providers/Vimeo.js +113 -19
- package/collections/media-providers/YouTube.js +74 -14
- package/collections/media-providers/index.js +3 -1
- package/collections/media-providers/style.js +52 -2
- package/components/Backdrop/index.js +95 -6
- package/components/Backdrop/spec.js +23 -1
- package/components/Backdrop/style.js +11 -2
- package/components/Button/index.js +47 -5
- package/components/Button/spec.js +36 -1
- package/components/Button/style.js +6 -1
- package/components/Checkbox/index.js +126 -32
- package/components/Checkbox/spec.js +94 -3
- package/components/Consume/helpers/buildParams.js +13 -2
- package/components/Consume/index.js +14 -2
- package/components/CountdownTimer/index.js +115 -17
- package/components/CountdownTimer/spec.js +126 -12
- package/components/Drawer/index.js +131 -16
- package/components/Drawer/spec.js +76 -1
- package/components/Drawer/style.js +37 -1
- package/components/Dropdown/index.js +65 -6
- package/components/Dropdown/style.js +4 -1
- package/components/Dropdown/transitions.js +34 -1
- package/components/Ellipsis/index.js +16 -2
- package/components/Ellipsis/spec.js +13 -1
- package/components/EmbeddedMedia/index.js +56 -6
- package/components/EmbeddedMedia/spec.js +52 -3
- package/components/ErrorBoundary/connector.js +9 -2
- package/components/ErrorBoundary/index.js +43 -7
- package/components/Grid/components/Item/index.js +40 -4
- package/components/Grid/components/Item/spec.js +23 -1
- package/components/Grid/components/Item/style.js +17 -3
- package/components/Grid/index.js +36 -4
- package/components/Grid/spec.js +23 -1
- package/components/Grid/style.js +11 -2
- package/components/HtmlSanitizer/connector.js +24 -3
- package/components/HtmlSanitizer/index.js +104 -12
- package/components/HtmlSanitizer/spec.js +207 -6
- package/components/I18n/components/FormatDate/index.js +26 -2
- package/components/I18n/components/FormatDate/spec.js +46 -1
- package/components/I18n/components/FormatNumber/index.js +34 -2
- package/components/I18n/components/FormatNumber/spec.js +41 -2
- package/components/I18n/components/FormatPrice/index.js +32 -2
- package/components/I18n/components/FormatPrice/spec.js +46 -1
- package/components/I18n/components/FormatTime/index.js +26 -2
- package/components/I18n/components/FormatTime/spec.js +43 -2
- package/components/I18n/components/I18nProvider/index.js +52 -9
- package/components/I18n/components/I18nProvider/spec.js +39 -1
- package/components/I18n/components/Placeholder/index.js +8 -2
- package/components/I18n/components/Placeholder/spec.js +30 -1
- package/components/I18n/components/Translate/index.js +68 -7
- package/components/I18n/components/Translate/spec.js +30 -1
- package/components/I18n/index.js +16 -1
- package/components/Icon/index.js +25 -2
- package/components/Icon/style.js +6 -1
- package/components/Image/Image.js +176 -19
- package/components/Image/ImageInner.js +48 -2
- package/components/Image/index.js +1 -1
- package/components/Image/style.js +29 -2
- package/components/InfiniteContainer/index.js +381 -49
- package/components/InfiniteContainer/spec.js +199 -10
- package/components/Input/components/DateInput.js +262 -6
- package/components/Input/components/MultiLineInput.js +98 -12
- package/components/Input/components/SimpleInput.js +207 -31
- package/components/Input/index.js +32 -3
- package/components/Input/spec.js +122 -1
- package/components/KeyboardConsumer/index.js +48 -7
- package/components/Link/connector.js +7 -1
- package/components/Link/index.js +96 -11
- package/components/Link/spec.js +56 -1
- package/components/Link/style.js +10 -1
- package/components/List/components/Item/index.js +35 -3
- package/components/List/components/Item/style.js +16 -1
- package/components/List/index.js +20 -2
- package/components/List/spec.js +31 -1
- package/components/Loading/index.js +6 -2
- package/components/Modal/index.js +38 -3
- package/components/Modal/style.js +36 -1
- package/components/ModalContainer/connector.js +17 -3
- package/components/ModalContainer/index.js +36 -3
- package/components/ModalContainer/spec.js +105 -5
- package/components/Picker/components/Button/index.js +34 -2
- package/components/Picker/components/Button/style.js +19 -1
- package/components/Picker/components/List/index.js +33 -2
- package/components/Picker/components/List/style.js +17 -1
- package/components/Picker/components/Modal/index.js +60 -7
- package/components/Picker/components/Modal/style.js +78 -1
- package/components/Picker/index.js +167 -21
- package/components/Picker/spec.js +83 -2
- package/components/Portal/index.js +130 -19
- package/components/ProductCharacteristics/connector.js +33 -4
- package/components/ProductCharacteristics/context.js +2 -1
- package/components/ProductCharacteristics/helpers/index.js +135 -21
- package/components/ProductCharacteristics/index.js +266 -31
- package/components/RangeSlider/components/Handle/index.js +25 -2
- package/components/RangeSlider/components/Handle/style.js +14 -1
- package/components/RangeSlider/helper.js +43 -8
- package/components/RangeSlider/index.js +228 -38
- package/components/RangeSlider/style.js +14 -1
- package/components/Route/RouteNotFound.js +46 -3
- package/components/Route/index.js +78 -10
- package/components/Router/connector.js +9 -2
- package/components/Router/index.js +237 -31
- package/components/ScannerContainer/connector.js +9 -2
- package/components/ScannerContainer/index.js +42 -6
- package/components/Select/components/Item/index.js +20 -4
- package/components/Select/components/Item/style.js +4 -1
- package/components/Select/index.js +149 -28
- package/components/Select/spec.js +86 -2
- package/components/Select/style.js +17 -1
- package/components/SelectBox/components/Item/index.js +47 -5
- package/components/SelectBox/components/Item/style.js +7 -1
- package/components/SelectBox/index.js +173 -17
- package/components/SelectBox/spec.js +59 -3
- package/components/SelectBox/style.js +18 -1
- package/components/Slider/index.js +6 -2
- package/components/SurroundPortals/index.js +26 -2
- package/components/Swiper/components/SwiperItem/index.js +28 -4
- package/components/Swiper/components/SwiperItem/spec.js +17 -1
- package/components/Swiper/components/SwiperItem/styles.js +5 -1
- package/components/Swiper/index.js +210 -18
- package/components/Swiper/styles.js +75 -7
- package/components/Toaster/index.js +10 -2
- package/components/Transition/index.js +89 -13
- package/components/Widgets/components/Widget/index.js +52 -4
- package/components/Widgets/components/Widget/spec.js +68 -3
- package/components/Widgets/components/Widget/style.js +21 -3
- package/components/Widgets/components/WidgetGrid/index.js +52 -7
- package/components/Widgets/components/WidgetGrid/spec.js +46 -2
- package/components/Widgets/components/WidgetGrid/style.js +8 -1
- package/components/Widgets/helpers/shouldShowWidget.js +44 -7
- package/components/Widgets/index.js +127 -15
- package/components/Widgets/spec.js +213 -6
- package/components/index.js +9 -1
- package/constants/ActionTypes.js +97 -19
- package/constants/Configuration.js +12 -2
- package/constants/Device.js +29 -2
- package/constants/DisplayOptions.js +8 -1
- package/constants/MenuIDs.js +2 -1
- package/constants/ModalTypes.js +1 -1
- package/constants/PageIDs.js +1 -1
- package/constants/Pipelines.js +7 -1
- package/constants/Portals.js +136 -3
- package/constants/Registration.js +3 -1
- package/constants/RoutePaths.js +13 -2
- package/constants/Tracking.js +3 -1
- package/constants/client.js +6 -1
- package/constants/ui.js +2 -1
- package/constants/user.js +6 -2
- package/context/index.js +33 -3
- package/helpers/config/index.js +139 -21
- package/helpers/config/mock.js +200 -8
- package/helpers/config/theme.js +50 -4
- package/helpers/data/index.js +204 -29
- package/helpers/data/spec.js +187 -7
- package/helpers/date/index.js +58 -6
- package/helpers/date/spec.js +92 -1
- package/helpers/dom/index.js +48 -11
- package/helpers/environment/index.js +14 -2
- package/helpers/html/decodeHTML.js +7 -1
- package/helpers/html/handleDOM.js +172 -21
- package/helpers/html/parseHTML.js +67 -12
- package/helpers/i18n/getDateFormatter.js +23 -4
- package/helpers/i18n/getNumberFormatter.js +32 -4
- package/helpers/i18n/getPriceFormatter.js +38 -4
- package/helpers/i18n/getTimeFormatter.js +23 -4
- package/helpers/i18n/getTranslator.js +62 -8
- package/helpers/i18n/index.js +5 -1
- package/helpers/i18n/mergeTranslations.js +36 -9
- package/helpers/i18n/messageCache.js +3 -1
- package/helpers/legacy/index.js +47 -9
- package/helpers/modal/withShowModal.js +13 -2
- package/helpers/portals/portalCollection.js +28 -6
- package/helpers/portals/routePortals.js +12 -1
- package/helpers/redux/compareObjects.js +7 -2
- package/helpers/redux/generateResultHash.js +36 -3
- package/helpers/redux/generateSortedHash.js +7 -2
- package/helpers/redux/hasExpired.js +10 -2
- package/helpers/redux/index.js +7 -1
- package/helpers/redux/mutable.js +143 -24
- package/helpers/redux/shouldFetchData.js +46 -10
- package/helpers/redux/shouldFetchFilters.js +17 -4
- package/helpers/router/index.js +49 -5
- package/helpers/style/index.js +43 -4
- package/helpers/style/spec.js +108 -2
- package/helpers/tracking/index.js +52 -9
- package/helpers/validation/index.js +39 -12
- package/helpers/validation/spec.js +10 -1
- package/package.json +3 -3
- package/providers/index.js +4 -1
- package/providers/loading/context.js +2 -1
- package/providers/loading/index.js +137 -22
- package/providers/toast/context.js +2 -1
- package/providers/toast/index.js +105 -11
- package/reducers/client/connectivity.js +22 -2
- package/reducers/client/index.js +7 -1
- package/reducers/client/info.js +27 -2
- package/reducers/index.js +23 -4
- package/reducers/menu/index.js +5 -1
- package/reducers/menu/menusById.js +41 -2
- package/reducers/modal/index.js +14 -2
- package/reducers/page/index.js +68 -5
- package/reducers/router/index.js +48 -2
- package/reducers/url/index.js +42 -3
- package/reducers/user/data.js +27 -2
- package/reducers/user/index.js +7 -1
- package/reducers/user/login.js +65 -2
- package/selectors/client.js +138 -21
- package/selectors/history.js +49 -11
- package/selectors/menu.js +34 -6
- package/selectors/modal.js +15 -4
- package/selectors/page.js +25 -4
- package/selectors/router.js +154 -30
- package/selectors/url.js +25 -4
- package/selectors/user.js +90 -13
- package/store/index.js +60 -6
- package/store/middelwares/logger.js +7 -1
- package/store/middelwares/streams.js +19 -2
- package/streams/app.js +60 -8
- package/streams/client.js +8 -2
- package/streams/error.js +14 -3
- package/streams/index.js +6 -1
- package/streams/interval.js +6 -2
- package/streams/main.js +27 -2
- package/streams/router.js +45 -8
- package/streams/user.js +89 -15
- package/streams/view.js +97 -25
- package/styles/reset/form.js +57 -5
- package/styles/reset/index.js +6 -1
- package/styles/reset/media.js +22 -1
- package/styles/reset/root.js +33 -1
- package/styles/reset/table.js +10 -1
- package/styles/reset/typography.js +26 -1
- package/subscriptions/app.js +148 -17
- package/subscriptions/error.js +292 -13
- package/subscriptions/helpers/buildRegisterUrl.js +25 -6
- package/subscriptions/helpers/clearUpInAppBrowser.js +14 -3
- package/subscriptions/helpers/handleLinks.js +267 -25
- package/subscriptions/helpers/pipeline.js +12 -1
- package/subscriptions/history.js +34 -6
- package/subscriptions/index.js +25 -4
- package/subscriptions/menu.js +22 -5
- package/subscriptions/mock.js +39 -7
- package/subscriptions/router.js +336 -23
- package/subscriptions/user.js +93 -3
package/collections/Redirects.js
CHANGED
|
@@ -1,46 +1,132 @@
|
|
|
1
|
-
|
|
1
|
+
import pathMatch from 'path-match';
|
|
2
|
+
import queryString from 'query-string';
|
|
3
|
+
|
|
4
|
+
/**
|
|
2
5
|
* The Redirects class.
|
|
3
|
-
*/
|
|
6
|
+
*/
|
|
7
|
+
class Redirects {
|
|
8
|
+
/**
|
|
4
9
|
* The constructor.
|
|
5
|
-
*/
|
|
10
|
+
*/
|
|
11
|
+
constructor() {
|
|
12
|
+
this.redirects = new Map();
|
|
13
|
+
this.matcher = pathMatch({
|
|
14
|
+
sensitive: false,
|
|
15
|
+
strict: false,
|
|
16
|
+
end: true
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
6
21
|
* Returns a specified element from the internal "redirects" Map object.
|
|
7
22
|
* @param {string} pathname The pathname to lookup.
|
|
8
23
|
* @private
|
|
9
24
|
* @returns {string|Function|Promise|null}
|
|
10
|
-
*/
|
|
25
|
+
*/
|
|
26
|
+
get(pathname) {
|
|
27
|
+
return this.redirects.get(pathname) || null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
11
31
|
* Returns the redirect for a passed pathname.
|
|
12
32
|
* @param {string} pathname The pathname to check.
|
|
13
33
|
* @return {string|Function|Promise|null}
|
|
14
|
-
*/
|
|
34
|
+
*/
|
|
35
|
+
getRedirect(pathname) {
|
|
36
|
+
/**
|
|
15
37
|
* Try to make a direct match with the pathname.
|
|
16
38
|
* If we get lucky then we don't have to iterate over the protected patterns.
|
|
17
|
-
*/
|
|
39
|
+
*/
|
|
40
|
+
let redirect = this.get(pathname);
|
|
41
|
+
|
|
42
|
+
/**
|
|
18
43
|
* If we didn't find a direct match then we need to match
|
|
19
44
|
* the given pathname against the protected patters.
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
45
|
+
*/
|
|
46
|
+
if (!redirect) {
|
|
47
|
+
// Get the protected patterns as an array.
|
|
48
|
+
const patterns = Array.from(this.redirects.keys());
|
|
49
|
+
const [withoutParams] = pathname.split('?');
|
|
50
|
+
|
|
51
|
+
// Loop over the patterns until a match is found.
|
|
52
|
+
const patternMatch = patterns.find(pattern => !!this.matcher(pattern)(withoutParams));
|
|
53
|
+
|
|
54
|
+
// Match found, set the redirect.
|
|
55
|
+
if (patternMatch) {
|
|
56
|
+
redirect = this.redirects.get(patternMatch);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return redirect;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
24
63
|
* @typedef RedirectExtendedData
|
|
25
64
|
* @property {string} matcher The value passed as "from" to set()
|
|
26
65
|
* @property {string|Function|Promise} handler The value passed as "to" to set()
|
|
27
66
|
* @property {Object} pathParams Decoded params from the pathname - defined within the matcher
|
|
28
67
|
* @property {Object} queryParams Decoded query params from the pathname
|
|
29
|
-
*/
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
/**
|
|
30
71
|
* Unlike "getRedirect" which only returns a matching handler for a passed pathname, this method
|
|
31
72
|
* returns an object that contains some extended data.
|
|
32
73
|
*
|
|
33
74
|
* @param {string} pathname The pathname to check.
|
|
34
75
|
* @returns {RedirectExtendedData}
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
76
|
+
*/
|
|
77
|
+
getRedirectExtended(pathname) {
|
|
78
|
+
const {
|
|
79
|
+
url,
|
|
80
|
+
query
|
|
81
|
+
} = queryString.parseUrl(pathname);
|
|
82
|
+
|
|
83
|
+
// At the fist check if there is a redirect for the pathname
|
|
84
|
+
const redirect = this.getRedirect(url);
|
|
85
|
+
if (!redirect) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Retrieve the matching pattern for the redirect from the redirects collection
|
|
90
|
+
const [patternMatch] = Array.from(this.redirects.entries()).find(([, handler]) => handler === redirect) || [];
|
|
91
|
+
const result = {
|
|
92
|
+
handler: redirect,
|
|
93
|
+
queryParams: JSON.parse(JSON.stringify(query))
|
|
94
|
+
};
|
|
95
|
+
if (patternMatch) {
|
|
96
|
+
// decode params from route patterns (e.g. /item/:productCode)
|
|
97
|
+
const matcherResult = this.matcher(patternMatch)(url);
|
|
98
|
+
result.matcher = patternMatch;
|
|
99
|
+
result.pathParams = matcherResult;
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
39
105
|
* Adds a redirect handler to the collection.
|
|
40
106
|
* @param {string} from The link to redirect from. Route patterns are also supported.
|
|
41
107
|
* @param {string|Function|Promise} to redirect / handle to create a dynamic link.
|
|
42
108
|
* @param {boolean} force Whether or not to forcefully set the redirect.
|
|
43
|
-
*/
|
|
109
|
+
*/
|
|
110
|
+
set(from = null, to = null, force = false) {
|
|
111
|
+
if (!from || !to) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (!force && this.redirects.has(from)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
this.redirects.set(from, to);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* eslint-disable extra-rules/potential-point-free */
|
|
121
|
+
|
|
122
|
+
/**
|
|
44
123
|
* Removes a specified element from the internal "redirects" Map object.
|
|
45
124
|
* @param {string} pathname The pathname to remove.
|
|
46
|
-
*/
|
|
125
|
+
*/
|
|
126
|
+
unset(pathname) {
|
|
127
|
+
this.redirects.delete(pathname);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* eslint-enable extra-rules/potential-point-free */
|
|
131
|
+
}
|
|
132
|
+
export default new Redirects();
|
package/collections/index.js
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export{default as authRoutes
|
|
1
|
+
export { default as authRoutes } from "./AuthRoutes";
|
|
2
|
+
export { default as persistedReducers } from "./PersistedReducers";
|
|
3
|
+
export { default as redirects } from "./Redirects";
|
|
4
|
+
export { default as embeddedMedia } from "./EmbeddedMedia";
|
|
5
|
+
export { default as configuration } from "./Configuration";
|
|
@@ -1,35 +1,103 @@
|
|
|
1
|
-
|
|
1
|
+
import { i18n, logger } from '@shopgate/engage/core/helpers';
|
|
2
|
+
import { PRIVACY_SETTINGS_PATTERN } from '@shopgate/engage/tracking/constants';
|
|
3
|
+
import { isRelativePosition, isAbsolutePosition } from "../../helpers/dom";
|
|
4
|
+
import styles from "./style";
|
|
5
|
+
const consentMessageIcon = `
|
|
6
|
+
<svg
|
|
7
|
+
width="100%"
|
|
8
|
+
height="100%"
|
|
9
|
+
viewBox="0 0 110 84"
|
|
10
|
+
version="1.1"
|
|
11
|
+
class="${styles.consentIcon}"
|
|
12
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
13
|
+
>
|
|
14
|
+
<g transform="matrix(1,0,0,1,-24.6099,-41.8178)">
|
|
15
|
+
<path d="M50.303,68.639L104.088,98.668L56.288,125.172C55.039,125.865 53.518,125.845 52.288,125.12C51.058,124.396 50.303,123.075 50.303,121.648L50.303,68.639ZM50.303,54.702L50.303,45.855C50.303,44.425 51.059,43.102 52.292,42.376C53.524,41.651 55.048,41.631 56.298,42.324C71.141,50.554 109.492,71.82 124.676,80.239C125.95,80.945 126.741,82.288 126.741,83.745C126.741,85.203 125.95,86.545 124.676,87.252L116.612,91.724L50.303,54.702Z" />
|
|
16
|
+
<g transform="matrix(0.944597,0.527391,-0.487489,0.873129,45.7069,-42.8282)">
|
|
17
|
+
<path d="M139,89C139,87.344 137.757,86 136.227,86L26.773,86C25.243,86 24,87.344 24,89C24,90.656 25.243,92 26.773,92L136.227,92C137.757,92 139,90.656 139,89Z" />
|
|
18
|
+
</g>
|
|
19
|
+
</g>
|
|
20
|
+
</svg>`;
|
|
21
|
+
|
|
22
|
+
/* eslint-disable class-methods-use-this */
|
|
23
|
+
|
|
24
|
+
/**
|
|
2
25
|
* The MediaProvider base class.
|
|
3
|
-
*/
|
|
26
|
+
*/
|
|
27
|
+
class MediaProvider {
|
|
28
|
+
/**
|
|
4
29
|
* Constructor.
|
|
5
30
|
* @param {Object} options The provider options.
|
|
6
31
|
* @param {boolean} [options.responsify=true] Whether to responsify the video containers.
|
|
7
|
-
*/
|
|
32
|
+
*/
|
|
33
|
+
constructor(options) {
|
|
34
|
+
this.containers = new Map();
|
|
35
|
+
this.isPending = false;
|
|
36
|
+
this.remoteScriptUrl = null;
|
|
37
|
+
this.options = {
|
|
38
|
+
responsify: options?.responsify ?? true
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
8
43
|
* Callback for when Provider script is loaded
|
|
9
44
|
* @callback
|
|
10
45
|
* @abstract
|
|
11
|
-
*/
|
|
46
|
+
*/
|
|
47
|
+
onScriptLoaded() {
|
|
48
|
+
logger.error('MediaProvider.onScriptLoaded() needs to be implemented within an inheriting class');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
12
52
|
* Callback to retrieve a list of media containers
|
|
13
53
|
* @callback
|
|
14
54
|
* @abstract
|
|
15
|
-
*/
|
|
55
|
+
*/
|
|
56
|
+
getMediaContainers() {
|
|
57
|
+
logger.error('MediaProvider.getMediaContainers() needs to be implemented within an inheriting class');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
16
61
|
* Applies optimizations to embedded media iframes within the given container.
|
|
17
62
|
* Common enhancements include adding responsive wrappers and appropriate
|
|
18
63
|
* sandbox attributes to improve security and layout behavior.
|
|
19
64
|
*
|
|
20
65
|
* @param {Document} document - The DOM document containing iframes to optimize.
|
|
21
66
|
* @returns {MediaProvider}
|
|
22
|
-
*/
|
|
67
|
+
*/
|
|
68
|
+
applyIframeOptimizations() {
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
23
73
|
* Optimizes video container to make it responsive.
|
|
24
74
|
* @param {Element} container A DOM container.
|
|
25
75
|
* @returns {MediaProvider}
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
76
|
+
*/
|
|
77
|
+
responsify(container) {
|
|
78
|
+
// Do not proceed when video responsify is disabled.
|
|
79
|
+
if (!this.options.responsify) return this;
|
|
80
|
+
|
|
81
|
+
// Remove fixed dimensions from the container.
|
|
82
|
+
container.removeAttribute('height');
|
|
83
|
+
container.removeAttribute('width');
|
|
84
|
+
if (isRelativePosition(container.parentNode) && isAbsolutePosition(container)) {
|
|
85
|
+
// Assume responsive embed code
|
|
86
|
+
container.parentNode.removeAttribute('style');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Create the wrapper and apply styling.
|
|
90
|
+
const wrapper = document.createElement('div');
|
|
91
|
+
wrapper.className = styles.responsiveContainer;
|
|
92
|
+
|
|
93
|
+
// Add the wrapper right before the container into the DOM.
|
|
94
|
+
container.parentNode.insertBefore(wrapper, container);
|
|
95
|
+
// Move the container into the wrapper.
|
|
96
|
+
wrapper.appendChild(container);
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
33
101
|
* Searches for embedded media and replaces it with a placeholder element when comfort cookie
|
|
34
102
|
* consent is not accepted.
|
|
35
103
|
*
|
|
@@ -41,27 +109,84 @@ wrapper.appendChild(container);return this;}/**
|
|
|
41
109
|
* @param {boolean} [cookieConsentSettings.statisticsCookiesAccepted] Whether statistics cookies
|
|
42
110
|
* are accepted.
|
|
43
111
|
* @returns {MediaProvider}
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
112
|
+
*/
|
|
113
|
+
handleCookieConsent(container, cookieConsentSettings = {}) {
|
|
114
|
+
const iframes = this.getMediaContainers(container);
|
|
115
|
+
if (!iframes.length || cookieConsentSettings.comfortCookiesAccepted !== false) {
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
iframes.forEach(iframe => {
|
|
119
|
+
// Add responsive container around iframes
|
|
120
|
+
this.responsify(iframe);
|
|
121
|
+
// Select the container and clear its content
|
|
122
|
+
const responsiveContainer = iframe.parentNode;
|
|
123
|
+
responsiveContainer.textContent = null;
|
|
124
|
+
// Add the consent message element to the container
|
|
125
|
+
this.injectCookieConsentMessage(responsiveContainer);
|
|
126
|
+
});
|
|
127
|
+
return this;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
48
131
|
* Injects a cookie consent message element into a container
|
|
49
132
|
* @param {Element} container A DOM container.
|
|
50
133
|
* @returns {MediaProvider}
|
|
51
|
-
*/
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
134
|
+
*/
|
|
135
|
+
injectCookieConsentMessage(container) {
|
|
136
|
+
// Create the wrapper for the message element
|
|
137
|
+
const messageWrapper = document.createElement('div');
|
|
138
|
+
messageWrapper.classList.add(styles.consentContainer, 'common__media-provider_cookie-consent-message-container');
|
|
139
|
+
|
|
140
|
+
// Add an SVG icon (implemented this way, since there where issues with document.createElement)
|
|
141
|
+
messageWrapper.innerHTML = consentMessageIcon;
|
|
142
|
+
|
|
143
|
+
// Create the main message and add it to the wrapper
|
|
144
|
+
const message = document.createElement('span');
|
|
145
|
+
message.classList.add('common__media-provider_cookie-consent-message-container_message');
|
|
146
|
+
message.innerHTML = i18n.text('htmlSanitizer.videoCookieConsent.message');
|
|
147
|
+
messageWrapper.appendChild(message);
|
|
148
|
+
|
|
149
|
+
// Create the link and add it to the wrapper
|
|
150
|
+
const link = document.createElement('a');
|
|
151
|
+
link.classList.add(styles.consentLink, 'common__media-provider_cookie-consent-message-container_link');
|
|
152
|
+
link.href = `${PRIVACY_SETTINGS_PATTERN}?source=video`;
|
|
153
|
+
link.innerHTML = i18n.text('htmlSanitizer.videoCookieConsent.link');
|
|
154
|
+
messageWrapper.appendChild(link);
|
|
155
|
+
|
|
156
|
+
// Add the wrapper to the container
|
|
157
|
+
container.appendChild(messageWrapper);
|
|
158
|
+
return this;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
57
162
|
* Add a DOM container with embedded videos.
|
|
58
163
|
* @param {NodeList} container A DOM container.
|
|
59
164
|
* @returns {MediaProvider}
|
|
60
|
-
*/
|
|
165
|
+
*/
|
|
166
|
+
add() {
|
|
167
|
+
logger.error('MediaProvider.add() needs to be implemented within an inheriting class');
|
|
168
|
+
return this;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
61
172
|
* Remove a DOM container.
|
|
62
173
|
* @param {NodeList} container A DOM container.
|
|
63
174
|
* @returns {MediaProvider}
|
|
64
|
-
*/
|
|
175
|
+
*/
|
|
176
|
+
remove(container) {
|
|
177
|
+
this.containers.delete(container);
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
65
182
|
* Stops all playing videos within the DOM containers.
|
|
66
183
|
* @returns {MediaProvider}
|
|
67
|
-
*/
|
|
184
|
+
*/
|
|
185
|
+
stop() {
|
|
186
|
+
logger.error('MediaProvider.stop() needs to be implemented within an inheriting class');
|
|
187
|
+
return this;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
export default MediaProvider;
|
|
191
|
+
|
|
192
|
+
/* eslint-enable class-methods-use-this */
|
|
@@ -1,43 +1,127 @@
|
|
|
1
|
-
|
|
1
|
+
import MediaProvider from "./MediaProvider";
|
|
2
|
+
|
|
3
|
+
/* eslint-disable class-methods-use-this */
|
|
4
|
+
|
|
5
|
+
const scriptUrl = 'https://player.vimeo.com/api/player.js';
|
|
6
|
+
/**
|
|
2
7
|
* The Vimeo media provider class.
|
|
3
|
-
*/
|
|
8
|
+
*/
|
|
9
|
+
class VimeoMediaProvider extends MediaProvider {
|
|
10
|
+
/**
|
|
4
11
|
* Constructor.
|
|
5
12
|
* @param {Object} options The provider options.
|
|
6
13
|
* @param {boolean} [options.responsify=true] Whether to responsify the video containers.
|
|
7
|
-
*/
|
|
8
|
-
|
|
14
|
+
*/
|
|
15
|
+
constructor(options) {
|
|
16
|
+
super(options);
|
|
17
|
+
// Need to check Vimeo.Player presence later
|
|
18
|
+
this.isPending = true;
|
|
19
|
+
this.remoteScriptUrl = scriptUrl;
|
|
20
|
+
this.deferred = [];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
9
24
|
* Retrieves a list of media containers for Vimeo.
|
|
10
25
|
* @param {ParentNode} container A DOM container that may contain Vimeo iframes.
|
|
11
26
|
* @returns {NodeListOf<Element>}
|
|
12
|
-
*/
|
|
27
|
+
*/
|
|
28
|
+
getMediaContainers(container) {
|
|
29
|
+
return container.querySelectorAll('iframe[src*="vimeo.com"]');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
13
33
|
* @inheritDoc
|
|
14
|
-
*/
|
|
34
|
+
*/
|
|
35
|
+
onScriptLoaded() {
|
|
36
|
+
this.isPending = false;
|
|
37
|
+
if (this.deferred.length) {
|
|
38
|
+
this.deferred.forEach(container => {
|
|
39
|
+
this.add(container);
|
|
40
|
+
});
|
|
41
|
+
this.deferred = [];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
15
46
|
* Check if the Provider script to be loaded externally is finished loading
|
|
16
47
|
* @returns {boolean}
|
|
17
|
-
*/
|
|
48
|
+
*/
|
|
49
|
+
checkScriptLoadingStatus() {
|
|
50
|
+
if (this.isPending && typeof window.Vimeo !== 'undefined') {
|
|
51
|
+
this.isPending = false;
|
|
52
|
+
}
|
|
53
|
+
return !this.isPending;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
18
57
|
* Add a DOM container with embedded videos.
|
|
19
58
|
* @override
|
|
20
59
|
* @param {ParentNode} container A DOM container.
|
|
21
60
|
* @returns {VimeoMediaProvider}
|
|
22
|
-
*/
|
|
61
|
+
*/
|
|
62
|
+
add(container) {
|
|
63
|
+
if (!this.checkScriptLoadingStatus()) {
|
|
64
|
+
this.deferred.push(container);
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
const iframes = this.getMediaContainers(container);
|
|
68
|
+
if (!iframes.length) {
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
const players = [];
|
|
72
|
+
iframes.forEach(iframe => {
|
|
73
|
+
players.push(new window.Vimeo.Player(iframe));
|
|
74
|
+
});
|
|
75
|
+
this.containers.set(container, players);
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
23
80
|
* Applies optimizations to embedded media iframes within the given container.
|
|
24
81
|
* Common enhancements include adding responsive wrappers and appropriate
|
|
25
82
|
* sandbox attributes to improve security and layout behavior.
|
|
26
83
|
*
|
|
27
84
|
* @param {Document} document - The DOM document containing iframes to optimize.
|
|
28
85
|
* @returns {YouTubeMediaProvider}
|
|
29
|
-
*/
|
|
30
|
-
|
|
86
|
+
*/
|
|
87
|
+
applyIframeOptimizations(document) {
|
|
88
|
+
const iframes = this.getMediaContainers(document);
|
|
89
|
+
if (!iframes.length) {
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
iframes.forEach((iframe, index) => {
|
|
93
|
+
// Block clicks on Vimeo icon
|
|
94
|
+
iframes[index].setAttribute('sandbox', 'allow-forms allow-scripts allow-pointer-lock allow-same-origin allow-top-navigation');
|
|
95
|
+
this.responsify(iframe);
|
|
96
|
+
});
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
31
101
|
* Stops all playing videos within the DOM containers.
|
|
32
102
|
* @override
|
|
33
103
|
* @returns {VimeoMediaProvider}
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
104
|
+
*/
|
|
105
|
+
stop() {
|
|
106
|
+
// Select all iframes in the document. Actually this should be done via the iframes
|
|
107
|
+
// registered in this.containers, but that doesn't seem to work reliably anymore.
|
|
108
|
+
// Since we had to find a quick fix for CURB-5033 we now select all iframes in the document
|
|
109
|
+
// via the media container selector and then stop the videos.
|
|
110
|
+
const iframes = this.getMediaContainers(document);
|
|
111
|
+
iframes.forEach(iframe => {
|
|
112
|
+
try {
|
|
113
|
+
const player = new window.Vimeo.Player(iframe);
|
|
114
|
+
player.pause().catch(() => {
|
|
115
|
+
// Ignore errors
|
|
116
|
+
});
|
|
117
|
+
} catch (e) {
|
|
118
|
+
// Ignore errors
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
41
125
|
* Searches for embedded media and replaces it with a placeholder element when comfort cookie
|
|
42
126
|
* consent is not accepted.
|
|
43
127
|
*
|
|
@@ -50,5 +134,15 @@ var iframes=this.getMediaContainers(document);iframes.forEach(function(iframe){t
|
|
|
50
134
|
* are accepted.
|
|
51
135
|
* @override
|
|
52
136
|
* @returns {VimeoMediaProvider}
|
|
53
|
-
*/
|
|
54
|
-
|
|
137
|
+
*/
|
|
138
|
+
handleCookieConsent(container, cookieConsentSettings) {
|
|
139
|
+
// Remove Vimeo player scripts since the VimeoMediaProvider has custom logic for it
|
|
140
|
+
container.querySelectorAll('script[src*="vimeo.com"]').forEach(entry => {
|
|
141
|
+
entry.remove();
|
|
142
|
+
});
|
|
143
|
+
return super.handleCookieConsent(container, cookieConsentSettings);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
export default VimeoMediaProvider;
|
|
147
|
+
|
|
148
|
+
/* eslint-enable class-methods-use-this */
|