1 | |
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | var isPhone = (cordova.platformId == 'windows') && WinJS.Utilities.isPhone;
|
23 | var isWp81 = navigator.appVersion.indexOf("Windows Phone 8.1") !== -1;
|
24 | var isWp10 = navigator.appVersion.indexOf("Windows Phone 10") !== -1;
|
25 | var isWin10UWP = navigator.appVersion.indexOf('MSAppHost/3.0') !== -1;
|
26 | var isHosted = window.location.protocol.indexOf('http') === 0;
|
27 | var isMsAppxWeb = window.location.protocol.indexOf('ms-appx-web') === 0;
|
28 |
|
29 | var schema = (isHosted || isWin10UWP && isMsAppxWeb) ? 'ms-appx-web' : 'ms-appx';
|
30 | var fileName = isPhone ? 'splashscreenphone.png' : 'splashscreen.png';
|
31 | var splashImageSrc = schema + ':///images/' + fileName;
|
32 |
|
33 | var splashElement = null, extendedSplashImage = null, extendedSplashProgress = null;
|
34 |
|
35 |
|
36 | var DEFAULT_SPLASHSCREEN_DURATION = 3000,
|
37 | DEFAULT_FADE_DURATION = 500,
|
38 | FPS = 60,
|
39 | PROGRESSRING_HEIGHT = 40,
|
40 | PROGRESSRING_BOTTOM_MARGIN = 10;
|
41 |
|
42 | var bgColor = "#464646",
|
43 | autoHideSplashScreen = true,
|
44 | splashScreenDelay = DEFAULT_SPLASHSCREEN_DURATION,
|
45 | fadeSplashScreen = true,
|
46 | fadeSplashScreenDuration = DEFAULT_FADE_DURATION,
|
47 | showSplashScreenSpinner = true,
|
48 | splashScreenSpinnerColor;
|
49 |
|
50 | var effectiveSplashDuration;
|
51 |
|
52 | function readBoolFromCfg(preferenceName, defaultValue, cfg) {
|
53 | var value = cfg.getPreferenceValue(preferenceName);
|
54 | if (typeof value !== 'undefined') {
|
55 | return value === 'true';
|
56 | } else {
|
57 | return defaultValue;
|
58 | }
|
59 | }
|
60 |
|
61 | function readPreferencesFromCfg(cfg) {
|
62 | try {
|
63 | bgColor = cfg.getPreferenceValue('SplashScreenBackgroundColor') || bgColor;
|
64 | bgColor = bgColor.replace('0x', '#').replace('0X', '#');
|
65 | if (bgColor.length > 7) {
|
66 |
|
67 | bgColor = bgColor.slice(0, 1) + bgColor.slice(3, bgColor.length);
|
68 | }
|
69 |
|
70 | autoHideSplashScreen = readBoolFromCfg('AutoHideSplashScreen', autoHideSplashScreen, cfg);
|
71 | splashScreenDelay = cfg.getPreferenceValue('SplashScreenDelay') || splashScreenDelay;
|
72 |
|
73 | fadeSplashScreen = readBoolFromCfg('FadeSplashScreen', fadeSplashScreen, cfg);
|
74 | fadeSplashScreenDuration = cfg.getPreferenceValue('FadeSplashScreenDuration') || fadeSplashScreenDuration;
|
75 |
|
76 | showSplashScreenSpinner = readBoolFromCfg('ShowSplashScreenSpinner', showSplashScreenSpinner, cfg);
|
77 | splashScreenSpinnerColor = cfg.getPreferenceValue('SplashScreenSpinnerColor');
|
78 |
|
79 | effectiveSplashDuration = Math.max(splashScreenDelay - fadeSplashScreenDuration, 0);
|
80 | } catch (e) {
|
81 | var msg = '[Windows][SplashScreen] Error occured on loading preferences from config.xml: ' + JSON.stringify(e);
|
82 | console.error(msg);
|
83 | }
|
84 | }
|
85 |
|
86 | function isPortrait() {
|
87 | return window.innerHeight > window.innerWidth;
|
88 | }
|
89 |
|
90 |
|
91 | function centerY() {
|
92 | if (isPortrait()) {
|
93 | if (window.screen.deviceYDPI === 172) {
|
94 | extendedSplashImage.style.transform = "translateY(22px)";
|
95 | } else if (window.screen.deviceYDPI === 230) {
|
96 | extendedSplashImage.style.transform = "translateY(25px)";
|
97 | } else if (window.screen.deviceYDPI === 211) {
|
98 | extendedSplashImage.style.transform = "translateY(27px)";
|
99 | }
|
100 | } else {
|
101 | extendedSplashImage.style.transform = "";
|
102 | }
|
103 | }
|
104 |
|
105 | function init(config) {
|
106 | readPreferencesFromCfg(config);
|
107 |
|
108 | var splashscreenStyles = document.createElement("link");
|
109 | splashscreenStyles.rel = 'stylesheet';
|
110 | splashscreenStyles.type = 'text/css';
|
111 | splashscreenStyles.href = '/www/css/splashscreen.css';
|
112 | document.head.appendChild(splashscreenStyles);
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 | splashElement = document.createElement('div');
|
120 | splashElement.id = 'extendedSplashScreen';
|
121 | splashElement.classList.add('extendedSplashScreen');
|
122 | splashElement.classList.add('hidden');
|
123 | splashElement.style.backgroundColor = bgColor;
|
124 |
|
125 | extendedSplashImage = document.createElement('img');
|
126 | extendedSplashImage.id = 'extendedSplashImage';
|
127 | extendedSplashImage.alt = 'Splash screen image';
|
128 |
|
129 |
|
130 | var draggableAttr = document.createAttribute('draggable');
|
131 | draggableAttr.value = 'false';
|
132 | extendedSplashImage.attributes.setNamedItem(draggableAttr);
|
133 |
|
134 | extendedSplashImage.style.left = '0px';
|
135 |
|
136 |
|
137 |
|
138 | var onloadAttr = document.createAttribute('onload');
|
139 | onloadAttr.value = '';
|
140 | extendedSplashImage.attributes.setNamedItem(onloadAttr);
|
141 | extendedSplashImage.src = splashImageSrc;
|
142 |
|
143 | extendedSplashProgress = document.createElement('progress');
|
144 | extendedSplashProgress.id = 'extendedSplashProgress';
|
145 | extendedSplashProgress.classList.add('win-medium');
|
146 | extendedSplashProgress.classList.add('win-ring');
|
147 |
|
148 | if (isWp81 || isWp10) {
|
149 | extendedSplashImage.style.maxWidth = "100%";
|
150 | extendedSplashImage.style.maxHeight = "100%";
|
151 | extendedSplashImage.src = splashImageSrc;
|
152 |
|
153 | extendedSplashImage.style.margin = "0 auto";
|
154 | extendedSplashImage.style.display = "block";
|
155 |
|
156 | extendedSplashImage.style.position = "relative";
|
157 | extendedSplashImage.style.top = "50%";
|
158 |
|
159 |
|
160 | if (isWp10) {
|
161 | extendedSplashImage.style.transform = "translateY(-50%)";
|
162 | } else {
|
163 | centerY();
|
164 | }
|
165 | }
|
166 |
|
167 | if (isWp81) {
|
168 | extendedSplashProgress.classList.add('extended-splash-progress-phone');
|
169 | } else if (isWp10) {
|
170 | extendedSplashProgress.classList.add('extended-splash-progress-wp10');
|
171 | }
|
172 |
|
173 | if (!showSplashScreenSpinner) {
|
174 | extendedSplashProgress.classList.add('hidden');
|
175 | }
|
176 | if (typeof splashScreenSpinnerColor !== 'undefined') {
|
177 | extendedSplashProgress.style.color = splashScreenSpinnerColor;
|
178 | }
|
179 |
|
180 | splashElement.appendChild(extendedSplashImage);
|
181 | splashElement.appendChild(extendedSplashProgress);
|
182 |
|
183 | document.body.appendChild(splashElement);
|
184 | }
|
185 |
|
186 |
|
187 |
|
188 | var origOverflow, origZooming;
|
189 |
|
190 | function disableUserInteraction() {
|
191 | origOverflow = document.documentElement.style.overflow;
|
192 | document.documentElement.style.overflow = 'hidden';
|
193 |
|
194 | origZooming = document.body.style['-ms-content-zooming'];
|
195 | document.body.style['-ms-content-zooming'] = 'none';
|
196 | }
|
197 |
|
198 | function enableUserInteraction() {
|
199 | document.documentElement.style.overflow = origOverflow;
|
200 | document.body.style['-ms-content-zooming'] = origZooming;
|
201 | }
|
202 |
|
203 |
|
204 | function show() {
|
205 | disableUserInteraction();
|
206 |
|
207 | positionControls();
|
208 |
|
209 |
|
210 | WinJS.Utilities.removeClass(extendedSplashScreen, 'hidden');
|
211 | }
|
212 |
|
213 | function positionControls() {
|
214 | if (isWp10) {
|
215 |
|
216 | if (splash.imageLocation.y !== 0) {
|
217 | if (isPortrait()) {
|
218 | extendedSplashProgress.style.top = window.innerHeight * (2/3 + 1/6) - PROGRESSRING_HEIGHT / 2 + 'px';
|
219 | } else {
|
220 | extendedSplashProgress.style.top = Math.min(window.innerHeight - PROGRESSRING_HEIGHT - PROGRESSRING_BOTTOM_MARGIN, splash.imageLocation.y + splash.imageLocation.height + 32) + 'px';
|
221 | }
|
222 | }
|
223 | return;
|
224 | }
|
225 |
|
226 |
|
227 | if (isPhone) {
|
228 | extendedSplashImage.style.top = 0;
|
229 | extendedSplashImage.style.left = 0;
|
230 | centerY();
|
231 | } else {
|
232 | extendedSplashImage.style.top = splash.imageLocation.y + 'px';
|
233 | extendedSplashImage.style.left = splash.imageLocation.x + 'px';
|
234 | }
|
235 |
|
236 | if (!isWp81) {
|
237 | extendedSplashImage.style.height = splash.imageLocation.height + 'px';
|
238 | extendedSplashImage.style.width = splash.imageLocation.width + 'px';
|
239 |
|
240 | extendedSplashProgress.style.marginTop = Math.min(window.innerHeight - PROGRESSRING_HEIGHT - PROGRESSRING_BOTTOM_MARGIN, splash.imageLocation.y + splash.imageLocation.height + 32) + 'px';
|
241 | }
|
242 | }
|
243 |
|
244 |
|
245 | function updateImageLocation() {
|
246 | if (isVisible()) {
|
247 | positionControls();
|
248 | }
|
249 | }
|
250 |
|
251 |
|
252 | function isVisible() {
|
253 | return !(WinJS.Utilities.hasClass(extendedSplashScreen, 'hidden'));
|
254 | }
|
255 |
|
256 | function fadeOut(el, duration, finishCb) {
|
257 | var opacityDelta = 1 / (FPS * duration / 1000);
|
258 | el.style.opacity = 1;
|
259 |
|
260 | (function fade() {
|
261 | if ((el.style.opacity -= opacityDelta) < 0) {
|
262 | finishCb();
|
263 | } else {
|
264 | requestAnimationFrame(fade);
|
265 | }
|
266 | })();
|
267 | }
|
268 |
|
269 |
|
270 | function hide() {
|
271 | if (isVisible()) {
|
272 | var hideFinishCb = function () {
|
273 | WinJS.Utilities.addClass(extendedSplashScreen, 'hidden');
|
274 | extendedSplashScreen.style.opacity = 1;
|
275 | enableUserInteraction();
|
276 | }
|
277 |
|
278 | if (fadeSplashScreen) {
|
279 | fadeOut(extendedSplashScreen, fadeSplashScreenDuration, hideFinishCb);
|
280 | } else {
|
281 | hideFinishCb();
|
282 | }
|
283 | }
|
284 | }
|
285 |
|
286 |
|
287 |
|
288 | var splash = null;
|
289 | var coordinates = { x: 0, y: 0, width: 0, height: 0 };
|
290 |
|
291 | function activated(eventObject) {
|
292 |
|
293 | splash = eventObject.detail.splashScreen;
|
294 |
|
295 |
|
296 | coordinates = splash.imageLocation;
|
297 |
|
298 |
|
299 | splash.addEventListener('dismissed', onSplashScreenDismissed, false);
|
300 |
|
301 |
|
302 |
|
303 | window.addEventListener('resize', onResize, false);
|
304 | }
|
305 |
|
306 | function onSplashScreenDismissed() {
|
307 |
|
308 | if (autoHideSplashScreen) {
|
309 | window.setTimeout(hide, effectiveSplashDuration);
|
310 | }
|
311 | }
|
312 |
|
313 | function onResize() {
|
314 |
|
315 | if (splash) {
|
316 |
|
317 | coordinates = splash.imageLocation;
|
318 | updateImageLocation(splash);
|
319 | }
|
320 | }
|
321 |
|
322 |
|
323 | module.exports = {
|
324 | firstShow: function (config, activatedEventArgs) {
|
325 | init(config);
|
326 | activated(activatedEventArgs);
|
327 |
|
328 | if (!isVisible() && (splashScreenDelay > 0 || !autoHideSplashScreen)) {
|
329 | show();
|
330 | }
|
331 | },
|
332 | show: function () {
|
333 | if (!isVisible()) {
|
334 | show();
|
335 | }
|
336 | },
|
337 | hide: function () {
|
338 | if (isVisible()) {
|
339 | hide();
|
340 | }
|
341 | }
|
342 | };
|