-
Notifications
You must be signed in to change notification settings - Fork 36
/
features.js
92 lines (88 loc) · 3.37 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
/**
* 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 mobile devices with small screens, `false` otherwise.
* - `has("tablet-like-channel")`: `true` for mobile devices bigger than phones, `false` otherwise.
* - `has("desktop-like-channel")`: `true` for non-mobile devices, `false` otherwise.
*
* In general pages should dynamically adjust to the browser viewport size, rather than relying
* on these static has() flags. They are only used by Combobox.
*
* The phone vs. mobile 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`.
*
* 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([
"ibm-decor/sniff",
"deliteful/channelBreakpoints"
], function (
has,
channelBreakpoints
) {
// 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") {
// Determine mobile or desktop by sniffing, rather than testing for TouchEvent etc.,
// as the latter will be true on desktop machines with touch screens.
// See https://stackoverflow.com/questions/3514784/what-is-the-best-way-to-detect-a-mobile-device.
// Note that sniffing for iOS is hard, due to a misleading userAgent, so leveraging decor/sniff.
var mobile = /Mobi|Android/i.test(navigator.userAgent) || has("ios");
// matched by screens at least as large as the "small" breakpoint
var mqAboveSmall = window.matchMedia("(min-device-width: " +
channelBreakpoints.smallScreen + ")");
has.add("phone-like-channel", function () {
return mobile && !mqAboveSmall.matches;
});
has.add("tablet-like-channel", function () {
return mobile && mqAboveSmall.matches;
});
has.add("desktop-like-channel", function () {
return !mobile;
});
}
// 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;
});