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/windows/44x44.png b/assets/defaultImages/windows/44x44.png
new file mode 100644
index 0000000..71e8bcc
Binary files /dev/null and b/assets/defaultImages/windows/44x44.png differ
diff --git a/assets/defaultImages/windows/71x71.png b/assets/defaultImages/windows/71x71.png
new file mode 100644
index 0000000..c5b2fd7
Binary files /dev/null and b/assets/defaultImages/windows/71x71.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...](/images/SplashScreen.scale-100.png)
+
+
+
+
+
+
+
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/package.json b/package.json
index 0ff9550..df0e32e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cordova-plugin-hostedwebapp",
- "version": "0.1.0",
+ "version": "0.1.1",
"description": "Hosted Web App Plugin",
"cordova": {
"id": "cordova-plugin-hostedwebapp",
diff --git a/plugin.xml b/plugin.xml
index 6276239..623f83f 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -1,7 +1,7 @@
+ version="0.1.1">
HostedWebApp
Hosted Web App Plugin
MIT License
@@ -11,15 +11,22 @@
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
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/replaceWindowsWrapperFiles.js b/scripts/replaceWindowsWrapperFiles.js
new file mode 100644
index 0000000..042a1d7
--- /dev/null
+++ b/scripts/replaceWindowsWrapperFiles.js
@@ -0,0 +1,140 @@
+#!/usr/bin/env node
+
+var fs = require('fs'),
+ path = require('path'),
+ url = require('url'),
+ etree,
+ 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);
+};
+
+function updateManifestFile(manifestPath) {
+ var contents = fs.readFileSync(manifestPath, 'utf-8');
+ if(contents) {
+ //Windows is the BOM. Skip the Byte Order Mark.
+ contents = contents.substring(contents.indexOf('<'));
+ }
+
+ var startPage = "www/wrapper.html";
+ var manifest = new etree.ElementTree(etree.XML(contents));
+ var appNode = manifest.find('.//Application');
+
+ appNode.attrib.StartPage = startPage;
+
+ // Write out manifest
+ fs.writeFileSync(manifestPath, manifest.write({indent: 4}), 'utf-8');
+}
+
+function updateWindowsManifests() {
+ var MANIFEST_WINDOWS8 = 'package.windows80.appxmanifest',
+ MANIFEST_WINDOWS = 'package.windows.appxmanifest',
+ MANIFEST_PHONE = 'package.phone.appxmanifest',
+ MANIFEST_WINDOWS10 = 'package.windows10.appxmanifest';
+
+ // Apply appxmanifest changes
+ [ MANIFEST_WINDOWS,
+ MANIFEST_WINDOWS8,
+ MANIFEST_PHONE,
+ MANIFEST_WINDOWS10 ].forEach(
+ function(manifestFile) {
+ updateManifestFile(path.join(projectRoot, "platforms", "windows", manifestFile));
+ });
+}
+
+module.exports = function (context) {
+ projectRoot = context.opts.projectRoot;
+
+ // if the windows folder does not exist, cancell the script
+ var windowsPath = path.join(projectRoot, "platforms","windows");
+ if (!fs.existsSync(windowsPath)) {
+ return;
+ }
+
+ etree = context.requireCordovaModule('cordova-lib/node_modules/elementtree');
+
+ // move contents of the assets folder to the windows platform dir
+ var Q = context.requireCordovaModule('q');
+
+ 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(err);
+ }
+
+ 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(err);
+ }
+
+ 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(err);
+ }
+
+ console.log("Finished copying wrapper css file for the windows platform.");
+
+ updateWindowsManifests();
+
+ task.resolve();
+ });
+ });
+ });
+
+ return task.promise;
+};
diff --git a/scripts/rollbackWindowsWrapperFiles.js b/scripts/rollbackWindowsWrapperFiles.js
new file mode 100644
index 0000000..7e47be4
--- /dev/null
+++ b/scripts/rollbackWindowsWrapperFiles.js
@@ -0,0 +1,104 @@
+#!/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;
+ }
+
+ var projectRoot = context.opts.projectRoot;
+
+ // if the windows folder does not exist, cancell the script
+ var windowsPath = path.join(projectRoot, "platforms","windows");
+ if (!fs.existsSync(windowsPath)) {
+ return;
+ }
+
+ Q = context.requireCordovaModule('q');
+ 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/updateConfigurationBeforePrepare.js
similarity index 96%
rename from scripts/test/updateConfiguration.js
rename to scripts/test/updateConfigurationBeforePrepare.js
index 4cac3fc..db6ff93 100644
--- a/scripts/test/updateConfiguration.js
+++ b/scripts/test/updateConfigurationBeforePrepare.js
@@ -1,7 +1,7 @@
'use strict';
process.env.NODE_ENV = 'test';
-var updateConfiguration = require('../updateConfiguration');
+var updateConfiguration = require('../updateConfigurationBeforePrepare');
var tu = require('./test-utils');
var assert = require('assert');
@@ -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/updateConfigurationAfterBuild.js b/scripts/updateConfigurationAfterBuild.js
deleted file mode 100644
index eb778ff..0000000
--- a/scripts/updateConfigurationAfterBuild.js
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env node
-
-var createConfigParser = require('./createConfigParser'),
- fs = require('fs'),
- path = require('path'),
- windowsConfig,
- projectRoot,
- etree;
-
-var logger = {
- log: function () {
- if (process.env.NODE_ENV !== 'test') {
- console.log.apply(this, arguments)
- }
- }
-};
-
-// 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 windowsDir = path.join(projectRoot, 'platforms', 'windows');
- if (fs.existsSync(windowsDir)) {
- var windowsXml = cordova_util.projectConfig(windowsDir);
- windowsConfig = createConfigParser(windowsXml, etree, ConfigParser);
- }
-}
-
-module.exports = function (context) {
- // create a parser for the Cordova configuration
- projectRoot = context.opts.projectRoot;
- configureParser(context);
-
- if (windowsConfig) {
- logger.log('Removing default images from windows configuration...');
- windowsConfig.removeElements('.//icon[@hap-default-image=\'yes\']');
- windowsConfig.removeElements('.//splash[@hap-default-image=\'yes\']');
-
- windowsConfig.write();
- }
-}
diff --git a/scripts/updateConfigurationAfterPrepare.js b/scripts/updateConfigurationAfterPrepare.js
index b6b292a..02bc7a5 100644
--- a/scripts/updateConfigurationAfterPrepare.js
+++ b/scripts/updateConfigurationAfterPrepare.js
@@ -4,7 +4,9 @@ var createConfigParser = require('./createConfigParser'),
fs = require('fs'),
path = require('path'),
config,
- windowsConfig,
+ windowsConfig,
+ androidConfig,
+ iosConfig,
projectRoot,
etree;
@@ -24,32 +26,64 @@ 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);
windowsConfig = createConfigParser(windowsXml, etree, ConfigParser);
}
+
+ var androidDir = path.join(projectRoot, 'platforms', 'android', 'res', 'xml');
+ if (fs.existsSync(androidDir)) {
+ var androidXml = cordova_util.projectConfig(androidDir);
+ androidConfig = createConfigParser(androidXml, etree, ConfigParser);
+ }
+
+ var iosProjectName = config.name();
+ if (iosProjectName) {
+ var iosDir = path.join(projectRoot, 'platforms', 'ios', iosProjectName);
+ if (fs.existsSync(iosDir)) {
+ var iosXml = cordova_util.projectConfig(iosDir);
+ iosConfig = createConfigParser(iosXml, etree, ConfigParser);
+ }
+ }
}
module.exports = function (context) {
- logger.log('Removing default images from cordova configuration...');
-
// create a parser for the Cordova configuration
projectRoot = context.opts.projectRoot;
configureParser(context);
- // Remove default images from configuration file
+ logger.log('Removing default images from Cordova configuration...');
+
+ // Remove default images from root configuration file
config.removeElements('.//icon[@hap-default-image=\'yes\']');
config.removeElements('.//splash[@hap-default-image=\'yes\']');
// 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.write();
+ // Remove default images from windows configuration file
+ windowsConfig.removeElements('.//icon[@hap-default-image=\'yes\']');
+ windowsConfig.removeElements('.//splash[@hap-default-image=\'yes\']');
+
+ windowsConfig.write();
+ }
+
+ if (androidConfig) {
+ // Remove default images from android configuration file
+ androidConfig.removeElements('.//icon[@hap-default-image=\'yes\']');
+ androidConfig.removeElements('.//splash[@hap-default-image=\'yes\']');
+
+ androidConfig.write();
+ }
+
+ if (iosConfig) {
+ // Remove default images from ios configuration file
+ iosConfig.removeElements('.//icon[@hap-default-image=\'yes\']');
+ iosConfig.removeElements('.//splash[@hap-default-image=\'yes\']');
+
+ iosConfig.write();
}
}
diff --git a/scripts/updateConfiguration.js b/scripts/updateConfigurationBeforePrepare.js
similarity index 96%
rename from scripts/updateConfiguration.js
rename to scripts/updateConfigurationBeforePrepare.js
index 9e20cc1..a19c453 100644
--- a/scripts/updateConfiguration.js
+++ b/scripts/updateConfigurationBeforePrepare.js
@@ -116,7 +116,7 @@ function configureParser(context) {
etree = context.requireCordovaModule('cordova-lib/node_modules/elementtree');
var xml = cordova_util.projectConfig(projectRoot);
- config = createConfigParser(xml, etree, ConfigParser);
+ config = createConfigParser(xml, etree, ConfigParser);
}
function processAccessRules(manifest) {
@@ -539,8 +539,10 @@ function processAndroidIcons(manifestIcons, outputConfiguration, previousIndent)
function processWindowsIcons(manifestIcons) {
var iconSizes = [
"30x30",
+ "44x44",
"106x106",
"70x70",
+ "71x71",
"170x170",
"150x150",
"360x360",
diff --git a/src/windows/HostedWebAppPluginProxy.js b/src/windows/HostedWebAppPluginProxy.js
index 2640361..cf26e25 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,27 @@ function configureWhiteList(manifest) {
}
}
+// hides the extended splash screen
+function hideExtendedSplashScreen(e) {
+ var extendedSplashScreen = document.getElementById("extendedSplashScreen");
+ extendedSplashScreen.style.display = "none";
+}
+
+// handle the hardware backbutton
+function navigateBack(e) {
+ if (!_mainView.canGoBack) {
+ return false;
+ }
+
+ try {
+ _mainView.goBack();
+ } catch (err) {
+ return false;
+ }
+
+ return true;
+}
+
module.exports = {
// loads the W3C manifest file and parses it
loadManifest: function (successCallback, errorCallback, args) {
@@ -231,5 +247,8 @@ 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
+ WinJS.Application.onbackclick = navigateBack;
+ });