forked from ibm-js/deliteful
-
Notifications
You must be signed in to change notification settings - Fork 0
/
features.js
98 lines (93 loc) · 3.87 KB
/
features.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/**
* This module leverages `requirejs-dplugins/has` and sets `has()` flags that can be
* used by multichannel widgets to determine the required channel:
*
* - `has("phone-like-channel")`: `true` for small screens, `false` otherwise.
* - `has("tablet-like-channel")`: `true` for medium screens, `false` otherwise.
* - `has("desktop-like-channel")`: `true` for large screens, `false` otherwise.
*
* These flags are set depending on the screen size, using CSS media queries that
* compare the actual screen width (the `device-width` media feature) with the corresponding
* breakpoint values provided by `deliteful/channelBreakpoints`.
*
* Note that the screen size is the only criteria used for determining
* the channel. When a channel flag is set to `true`, the other channel flags are set
* to `false`.
*
* The default values of the breakpoints can be configured using `require.config()`.
* For details, see the documentation of `deliteful/channelBreakpoints`.
*
* The channel can be configured statically using `require.config()`, for instance:
*
* ```html
* <script>
* // configuring RequireJS
* require.config({
* ...
* config: {
* "requirejs-dplugins/has": {
* "phone-like-channel": false,
* "tablet-like-channel": true,
* "desktop-like-channel": false,
* }
* }
* });
* </script>
* ```
* Note that only one channel flag should be set to `true`.
*
* The module returns the `has()` function returned by the module `requirejs-dplugins/has`.
*
* @module deliteful/features
*/
define(["requirejs-dplugins/has", "deliteful/channelBreakpoints"],
function (has, channelBreakpoints) {
// Notes:
// - Use the device-width media feature rather than width, such that, on
// desktop/laptop, the selected channel does not depend on the actual size of the
// viewport. Thus, the selected channel depends only on the static characteristics
// of the device (its screen width), which fits the use-case of multichannel
// widgets that need a statically determined channel. Otherwise it would be confusing
// to get a different channel depending on whether the app is initially loaded
// in a small or large viewport.
// - We do not technically enforce the "small" breakpoint to be smaller than the
// medium one. Hence the apparently redundant checks of both media queries
// for the small and large channels.
// The build system evaluates the function of plugin modules while running
// in nodejs. Hence the need to test for presence of window. The value of
// the has-features does not matter at build time. (#512)
if (typeof window !== "undefined") {
// matched by screens at least as large as the "small" breakpoint
var mqAboveSmall = window.matchMedia("(min-device-width: " +
channelBreakpoints.smallScreen + ")");
// matched by screens at least as large as the "medium" breakpoint
var mqAboveMedium = window.matchMedia("(min-device-width: " +
channelBreakpoints.mediumScreen + ")");
has.add("phone-like-channel", function () {
return !mqAboveSmall.matches && !mqAboveMedium.matches;
});
has.add("tablet-like-channel", function () {
return mqAboveSmall.matches && !mqAboveMedium.matches;
});
has.add("desktop-like-channel", function () {
return mqAboveSmall.matches && mqAboveMedium.matches;
});
}
// Does browser have support for CSS animations ?
has.add("animationEndEvent", function () {
var animationEndEvents = {
"animation": "animationend", // > IE10, FF
"-webkit-animation": "webkitAnimationEnd", // > chrome 1.0 , > Android 2.1 , > Safari 3.2
"-ms-animation": "MSAnimationEnd" // IE 10
};
// NOTE: returns null if event is not supported
var fakeElement = document.createElement("fakeElement");
for (var event in animationEndEvents) {
if (fakeElement.style[event] !== undefined) {
return animationEndEvents[event];
}
}
return null;
});
return has;
});