diff --git a/assets/defaultImages/windows/1152x1920.png b/assets/defaultImages/windows/1152x1920.png index abf283d..bf0769b 100644 Binary files a/assets/defaultImages/windows/1152x1920.png and b/assets/defaultImages/windows/1152x1920.png differ diff --git a/assets/defaultImages/wp8/480x800.png b/assets/defaultImages/wp8/480x800.png index bd39266..8a8b8bb 100644 Binary files a/assets/defaultImages/wp8/480x800.png and b/assets/defaultImages/wp8/480x800.png differ diff --git a/assets/windows/wrapper.css b/assets/windows/wrapper.css new file mode 100644 index 0000000..1c534f1 --- /dev/null +++ b/assets/windows/wrapper.css @@ -0,0 +1 @@ +body { width: 100%; height: 100%; position: absolute; top: 0; left: 0; margin: 0; } .loading-progress { position: absolute; top: 50%; left: 45%; width: 10%; } .extendedSplashScreen .loading-progress { position: absolute; top: 50%; left: 20%; width: 60%; margin: 0; } .extendedSplashScreen { display: block; background-color: #000000; height: 100%; width: 100%; position: absolute; top: 0px; left: 0px; text-align: center; z-index: 10111; } .extendedSplashScreen .extendedSplashImage { position: absolute; } \ No newline at end of file diff --git a/assets/windows/wrapper.html b/assets/windows/wrapper.html new file mode 100644 index 0000000..c9cb6a5 --- /dev/null +++ b/assets/windows/wrapper.html @@ -0,0 +1,19 @@ + + + + + + + + Hello World + + +
+ Launching... + +
+ + + + + diff --git a/assets/windows/wrapper.js b/assets/windows/wrapper.js new file mode 100644 index 0000000..6399e53 --- /dev/null +++ b/assets/windows/wrapper.js @@ -0,0 +1,70 @@ +var setupExtendedSplashScreen, updateSplashScreenPositioning, + splashScreen, splashScreenEl, splashScreenImageEl, + isWindows = navigator.appVersion.indexOf("Windows Phone 8.1") === -1; + +WinJS.Application.addEventListener("activated", function (e) { + if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) { + splashScreen = e.detail.splashScreen; + + // Listen for window resize events to reposition the extended splash screen image accordingly. + // This is important to ensure that the extended splash screen is formatted properly in response to snapping, unsnapping, rotation, etc... + window.addEventListener("resize", updateSplashPositioning, false); + + var previousExecutionState = e.detail.previousExecutionState; + var state = Windows.ApplicationModel.Activation.ApplicationExecutionState; + if (previousExecutionState === state.notRunning + || previousExecutionState === state.terminated + || previousExecutionState === state.closedByUser) { + setupExtendedSplashScreen(); + } + } +}, false); + +setupExtendedSplashScreen = function () { + splashScreenEl = document.getElementById("extendedSplashScreen"); + splashScreenImageEl = (splashScreenEl && splashScreenEl.querySelector(".extendedSplashImage")); + splashLoadingEl = (splashScreenEl && splashScreenEl.querySelector(".loading-progress")); + + if (!splashScreen || !splashScreenEl || !splashScreenImageEl) { return; } + + var imgSrc = "/images/splashScreenPhone.png" + if (isWindows) { + imgSrc = "/images/SplashScreen.png" + } + + splashScreenImageEl.setAttribute("src", imgSrc); + + updateSplashPositioning(); + + // Once the extended splash screen is setup, apply the CSS style that will make the extended splash screen visible. + splashScreenEl.style.display = "block"; +}; + +updateSplashPositioning = function () { + if (!splashScreen || !splashScreenImageEl) { return; } + // Position the extended splash screen image in the same location as the system splash screen image. + if (isWindows) { + splashScreenImageEl.style.top = splashScreen.imageLocation.y + "px"; + splashScreenImageEl.style.left = splashScreen.imageLocation.x + "px"; + splashScreenImageEl.style.height = splashScreen.imageLocation.height + "px"; + splashScreenImageEl.style.width = splashScreen.imageLocation.width + "px"; + } else { + var curOrientation = Windows.Devices.Sensors.SimpleOrientationSensor.getDefault().getCurrentOrientation(); + if ((curOrientation == Windows.Devices.Sensors.SimpleOrientation.rotated270DegreesCounterclockwise || curOrientation == Windows.Devices.Sensors.SimpleOrientation.rotated90DegreesCounterclockwise) && + Windows.Graphics.Display.DisplayInformation.autoRotationPreferences != Windows.Graphics.Display.DisplayOrientations.portrait) { + splashScreenImageEl.src = "/images/splashscreen.png"; + } else { + splashScreenImageEl.src = "/images/splashScreenPhone.png"; + } + splashScreenImageEl.style.width = "100%"; + splashScreenImageEl.style.height = "100%"; + } + + if (splashLoadingEl) { + if (isWindows) { + splashLoadingEl.style.top = (splashScreen.imageLocation.y + splashScreen.imageLocation.height + 20) + "px"; + } else { + splashLoadingEl.style.top = (window.innerHeight * 0.8) + "px"; + } + } +}; diff --git a/plugin.xml b/plugin.xml index 6276239..0ac6bfa 100644 --- a/plugin.xml +++ b/plugin.xml @@ -11,11 +11,11 @@ - + - + @@ -37,6 +37,8 @@ + + diff --git a/readme.md b/readme.md index 71a566a..832ca4b 100644 --- a/readme.md +++ b/readme.md @@ -205,3 +205,6 @@ Cordova for Android and iOS platforms provide a security policy to control which The Windows and Windows Phone platforms do not provide control for these kind of requests, and they will be allowed. +## Changelog + +Releases are documented in [GitHub](https://github.com/manifoldjs/ManifoldCordova/releases). \ No newline at end of file diff --git a/scripts/replaceWindowsWrapperFile.js b/scripts/replaceWindowsWrapperFile.js new file mode 100644 index 0000000..3c313b2 --- /dev/null +++ b/scripts/replaceWindowsWrapperFile.js @@ -0,0 +1,96 @@ +#!/usr/bin/env node + +var fs = require('fs'), + path = require('path'), + url = require('url'), + projectRoot; + +var logger = { + log: function () { + if (process.env.NODE_ENV !== 'test') { + console.log.apply(this, arguments) + } + }, + warn: function() { + if (process.env.NODE_ENV !== 'test') { + console.warn.apply(this, arguments) + } + } +}; + +function copyFile(source, target, callback) { + var cbCalled = false; + + function done(err) { + if (!cbCalled) { + callback(err); + cbCalled = true; + } + } + + var rd = fs.createReadStream(source); + rd.on('error', done); + + var wr = fs.createWriteStream(target); + wr.on('error', done); + wr.on('close', function() { + done(); + }); + rd.pipe(wr); +}; + +module.exports = function (context) { + // move contents of the assets folder to the windows platform dir + var Q = context.requireCordovaModule('q'); + + // create a parser for the Cordova configuration + projectRoot = context.opts.projectRoot; + var filename = "wrapper"; + + var sourcePath = path.resolve(__dirname, "..", "assets", "windows", "wrapper.html"); + var destPath = path.join(projectRoot, "platforms","windows", "www", filename + ".html"); + + logger.log('Copying wrapper html file for the windows platform from '+ sourcePath + ' to ' + destPath + '.'); + + var task = Q.defer(); + copyFile(sourcePath, destPath, function (err) { + if (err) { + console.error(err); + return task.reject(); + } + + console.log("Finished copying wrapper html file for the windows platform."); + + var sourcePath = path.resolve(__dirname, "..", "assets", "windows", "wrapper.js"); + var destPath = path.join(projectRoot, "platforms", "windows", "www", "js", filename +".js"); + + logger.log('Copying wrapper js file for the windows platform from '+ sourcePath + ' to ' + destPath + '.'); + + copyFile(sourcePath, destPath, function (err) { + if (err) { + console.error(err); + return task.reject(); + } + + console.log("Finished copying wrapper js file for the windows platform."); + + var sourcePath = path.resolve(__dirname, "..", "assets", "windows", "wrapper.css"); + var destPath = path.join(projectRoot, "platforms", "windows", "www", "css", filename + ".css"); + + logger.log('Copying wrapper css file for the windows platform from '+ sourcePath + ' to ' + destPath + '.'); + + copyFile(sourcePath, destPath, function (err) { + if (err) { + console.error(err); + return task.reject(); + } + + console.log("Finished copying wrapper css file for the windows platform."); + + task.resolve(); + }); + }); + }); + + return task.promise; +}; diff --git a/scripts/rollbackWindowsWrapperFiles.js b/scripts/rollbackWindowsWrapperFiles.js new file mode 100644 index 0000000..6d41c12 --- /dev/null +++ b/scripts/rollbackWindowsWrapperFiles.js @@ -0,0 +1,97 @@ +#!/usr/bin/env node + +var createConfigParser = require('./createConfigParser'), + fs = require('fs'), + path = require('path'), + url = require('url'), + pendingTasks = [], + Q, + config, + projectRoot, + etree; + +var logger = { + log: function () { + if (process.env.NODE_ENV !== 'test') { + console.log.apply(this, arguments) + } + }, + warn: function() { + if (process.env.NODE_ENV !== 'test') { + console.warn.apply(this, arguments) + } + } +}; + +function deleteFile(path) { + var t = Q.defer(); + pendingTasks.push(t); + + logger.log('Deleting ' + path + ' file for the windows platform.'); + + fs.unlink(path, function (err) { + if (err) { + console.log(err); + return t.reject(); + } + + t.resolve(); + }); +} + +// Configure Cordova configuration parser +function configureParser(context) { + var cordova_util = context.requireCordovaModule('cordova-lib/src/cordova/util'), + ConfigParser = context.requireCordovaModule('cordova-lib/src/configparser/ConfigParser'); + etree = context.requireCordovaModule('cordova-lib/node_modules/elementtree'); + + var xml = cordova_util.projectConfig(context.opts.projectRoot); + config = createConfigParser(xml, etree, ConfigParser); +} + +module.exports = function (context) { + // If the plugin is not being removed, cancel the script + if (context.opts.plugins.indexOf(context.opts.plugin.id) == -1) { + return; + } + + Q = context.requireCordovaModule('q'); + var projectRoot = context.opts.projectRoot; + var task = Q.defer(); + + var destPath = path.join(projectRoot, "platforms", "windows", "www", "wrapper.html"); + if (fs.existsSync(destPath)) { + deleteFile(destPath); + } + + destPath = path.join(projectRoot, "platforms", "windows", "www", "js", "wrapper.js"); + + if (fs.existsSync(destPath)) { + deleteFile(destPath); + } + + destPath = path.join(projectRoot, "platforms", "windows", "www", "css", "wrapper.css"); + + if (fs.existsSync(destPath)) { + deleteFile(destPath); + } + + Q.allSettled(pendingTasks).then(function (e) { + console.log("Finished removing assets for the windows platform."); + + // restore content source to index.html in all platforms. + configureParser(context); + if (config) { + console.log("Restoring content source value to index.html"); + config.setAttribute('content', 'src', 'index.html'); + config.write(); + } + else { + console.log("could not load config.xml file"); + } + + task.resolve(); + }); + + return task.promise; +}; diff --git a/scripts/test/updateConfiguration.js b/scripts/test/updateConfiguration.js index 4cac3fc..e284c9a 100644 --- a/scripts/test/updateConfiguration.js +++ b/scripts/test/updateConfiguration.js @@ -17,7 +17,7 @@ function initializeContext(testDir) { var ctx = { opts : { plugin: { - id: 'com-manifoldjs-hostedwebapp' + id: 'cordova-plugin-hostedwebapp' }, projectRoot : testDir } diff --git a/scripts/updateConfigurationAfterPrepare.js b/scripts/updateConfigurationAfterPrepare.js index b6b292a..c16d97b 100644 --- a/scripts/updateConfigurationAfterPrepare.js +++ b/scripts/updateConfigurationAfterPrepare.js @@ -24,7 +24,7 @@ function configureParser(context) { var xml = cordova_util.projectConfig(projectRoot); config = createConfigParser(xml, etree, ConfigParser); - + var windowsDir = path.join(projectRoot, 'platforms', 'windows'); if (fs.existsSync(windowsDir)) { var windowsXml = cordova_util.projectConfig(windowsDir); @@ -45,11 +45,11 @@ module.exports = function (context) { // save the updated configuration config.write(); - + if (windowsConfig) { // Patch for windows: restoring the start page to index.html logger.log('Restoring local start page in windows configuration...'); - windowsConfig.setAttribute('content', 'src', 'index.html'); + windowsConfig.setAttribute('content', 'src', 'wrapper.html'); windowsConfig.write(); } } diff --git a/src/windows/HostedWebAppPluginProxy.js b/src/windows/HostedWebAppPluginProxy.js index 2640361..0ca856a 100644 --- a/src/windows/HostedWebAppPluginProxy.js +++ b/src/windows/HostedWebAppPluginProxy.js @@ -10,11 +10,6 @@ var _whiteList = []; // creates a webview to host content function configureHost(url, zOrder, display) { - - // workaround to avoid the webview scaling issue - var div = document.getElementById("deviceready"); - div.classList.remove("blink"); - var webView = document.createElement(cordova.platformId === 'windows8' ? 'iframe' : 'x-ms-webview'); var style = webView.style; style.position = 'absolute'; @@ -166,6 +161,12 @@ function configureWhiteList(manifest) { } } +// hides the extended splash screen +function hideExtendedSplashScreen(e) { + var extendedSplashScreen = document.getElementById("extendedSplashScreen"); + extendedSplashScreen.style.display = "none"; +} + module.exports = { // loads the W3C manifest file and parses it loadManifest: function (successCallback, errorCallback, args) { @@ -231,5 +232,7 @@ module.exports.loadManifest( configureOfflineSupport('offline.html'); configureWhiteList(manifest); _mainView = configureHost(manifest ? manifest.start_url : 'about:blank', _zIndex); + _mainView.addEventListener("MSWebViewDOMContentLoaded", hideExtendedSplashScreen, false); + cordova.fireDocumentEvent("webviewCreated", { webView: _mainView }); - }); \ No newline at end of file + });