Repository: cordova-windows Updated Branches: refs/heads/master e8b239a29 -> b796bd75c
CB-10831 Apply app description to appxmanifest files This closes #160 Project: http://git-wip-us.apache.org/repos/asf/cordova-windows/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-windows/commit/b796bd75 Tree: http://git-wip-us.apache.org/repos/asf/cordova-windows/tree/b796bd75 Diff: http://git-wip-us.apache.org/repos/asf/cordova-windows/diff/b796bd75 Branch: refs/heads/master Commit: b796bd75c61ab7243ea08ab3883a41d93660a625 Parents: e8b239a Author: Vladimir Kotikov <kotikov.vladi...@gmail.com> Authored: Tue Mar 15 13:39:44 2016 +0300 Committer: Vladimir Kotikov <kotikov.vladi...@gmail.com> Committed: Fri Mar 18 12:16:53 2016 +0300 ---------------------------------------------------------------------- spec/unit/Prepare.Win10.spec.js | 75 ++++++++++++++++++++++++++++++- template/cordova/lib/AppxManifest.js | 49 +++++++++++++++++++- template/cordova/lib/prepare.js | 11 +++++ 3 files changed, 132 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/b796bd75/spec/unit/Prepare.Win10.spec.js ---------------------------------------------------------------------- diff --git a/spec/unit/Prepare.Win10.spec.js b/spec/unit/Prepare.Win10.spec.js index 98b75c6..b0d671d 100644 --- a/spec/unit/Prepare.Win10.spec.js +++ b/spec/unit/Prepare.Win10.spec.js @@ -56,6 +56,7 @@ function createMockConfigAndManifestForApplyCoreProperties(startPage, preference /* jshint proto: false */ var config = { version: function() { return '1.0.0.0'; }, + description: function () { return 'CordovaApp'; }, windows_packageVersion: function() { return winPackageVersion; }, name: function() { return 'HelloCordova'; }, packageName: function() { return 'org.apache.cordova.HelloCordova'; }, @@ -123,7 +124,7 @@ describe('Windows 10 project', function() { var app = mockConfig.manifest.doc.find('.//Application'); // Workaround to avoid WWAHost.exe bug: https://issues.apache.org/jira/browse/CB-10446 - var isAppxWebStartupUri = app.attrib.StartPage === 'ms-appx-web:///www/index.html' || + var isAppxWebStartupUri = app.attrib.StartPage === 'ms-appx-web:///www/index.html' || app.attrib.StartPage === 'ms-appx-web://' + mockConfig.config.packageName().toLowerCase() + '/www/index.html'; expect(isAppxWebStartupUri).toBe(true); }); @@ -380,3 +381,75 @@ describe('A Windows 10 project should apply the uap: namespace prefix to certain expect(testResults.location).toBe('DeviceCapability'); }); }); + + +function createMockConfigAndManifestForDescription(description) { + var config = { + version: function() { return '1.0.0.0'; }, + name: function() { return 'HelloCordova'; }, + description: function () { return description; }, + packageName: function() { return 'org.apache.cordova.HelloCordova'; }, + author: function() { return 'Apache'; }, + startPage: function() { return 'index.html'; }, + windows_packageVersion: function() { return; }, + getPreference: function () { return; } + }; + + var manifest = AppxManifest.get(Win81ManifestPath, /*ignoreCache=*/true); + spyOn(fs, 'writeFileSync'); + + return { config: config, manifest: manifest }; +} + +describe('Package description', function () { + it('should be applied to both Properties and VisualElements nodes', function () { + var mockConfig = createMockConfigAndManifestForDescription('My custom description'); + applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'uap:', true); + + var desc = mockConfig.manifest.doc.find('.//Properties/Description'); + expect(desc.text).toBe('My custom description'); + + desc = mockConfig.manifest.doc.find('.//Application/m2:VisualElements'); + expect(desc.attrib.Description).toBe('My custom description'); + }); + + it('should not be removed from VisualElements node', function () { + var mockConfig = createMockConfigAndManifestForDescription(); + applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'uap:', true); + + var desc = mockConfig.manifest.doc.find('.//Properties/Description'); + expect(desc).toBe(null); + + desc = mockConfig.manifest.doc.find('.//Application/m2:VisualElements'); + expect(desc.attrib.Description).toEqual(prepare.__get__('DEFAULT_DESCRIPTION')); + }); + + it('should be stripped to 2048 symbols before adding to manifest', function () { + var veryLongDescription = (new Array(3*1024)).join('x'); + var mockConfig = createMockConfigAndManifestForDescription(veryLongDescription); + + expect(function () { + applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'uap:', true); + }).not.toThrow(); + + var desc = mockConfig.manifest.doc.find('.//Properties/Description'); + expect(desc.text.length).toBe(2048); + + desc = mockConfig.manifest.doc.find('.//Application/m2:VisualElements'); + expect(desc.attrib.Description.length).toBe(2048); + }); + + it('should be validated before adding to manifest', function () { + var mockConfig = createMockConfigAndManifestForDescription('My description with \t and \n symbols'); + + expect(function () { + applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'uap:', true); + }).not.toThrow(); + + var desc = mockConfig.manifest.doc.find('.//Properties/Description'); + expect(desc).not.toMatch(/\n|\t/); + + desc = mockConfig.manifest.doc.find('.//Application/m2:VisualElements'); + expect(desc.attrib.Description).not.toMatch(/\n|\t/); + }); +}); http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/b796bd75/template/cordova/lib/AppxManifest.js ---------------------------------------------------------------------- diff --git a/template/cordova/lib/AppxManifest.js b/template/cordova/lib/AppxManifest.js index 8c934e6..465f698 100644 --- a/template/cordova/lib/AppxManifest.js +++ b/template/cordova/lib/AppxManifest.js @@ -211,7 +211,29 @@ AppxManifest.prototype.getProperties = function () { publisher.text = name; return this; - } + }, + getDescription: function () { + var description = properties.find('./Description'); + return description && description.text; + }, + setDescription: function (text) { + + var description = properties.find('./Description'); + + if (!text || text.length === 0) { + if (description) properties.remove(description); + return this; + } + + if (!description) { + description = new et.Element('Description'); + properties.append(description); + } + + description.text = processDescription(text); + + return this; + }, }; }; @@ -368,7 +390,17 @@ AppxManifest.prototype.getVisualElements = function () { } return this; - } + }, + getDescription: function () { + return visualElements.attrib.Description; + }, + setDescription: function (description) { + if (!description || description.length === 0) + throw new TypeError('VisualElements.Description attribute must be defined and non-empty'); + + visualElements.attrib.Description = processDescription(description); + return this; + }, }; }; @@ -403,6 +435,19 @@ function refineColor(color) { return '#' + color; } +function processDescription(text) { + var result = text; + + // Description value limitations: https://msdn.microsoft.com/en-us/library/windows/apps/br211429.aspx + // value should be no longer than 2048 characters + if (text.length > 2048) { + result = text.substr(0, 2048); + } + + // value should not contain newlines and tabs + return result.replace(/(\n|\r)/g, ' ').replace(/\t/g, ' '); +} + // Shortcut for getIdentity.setName AppxManifest.prototype.setPackageName = function (name) { this.getIdentity().setName(name); http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/b796bd75/template/cordova/lib/prepare.js ---------------------------------------------------------------------- diff --git a/template/cordova/lib/prepare.js b/template/cordova/lib/prepare.js index a7ae786..ca90fab 100644 --- a/template/cordova/lib/prepare.js +++ b/template/cordova/lib/prepare.js @@ -29,6 +29,10 @@ var ConfigParser = require('./ConfigParser'); var events = require('cordova-common').events; var xmlHelpers = require('cordova-common').xmlHelpers; +// Default value for VisualElements' Description attribute. +// This is equal to the value that comes with default App template +var DEFAULT_DESCRIPTION = 'CordovaApp'; + var PROJECT_WINDOWS10 = 'CordovaApp.Windows10.jsproj', MANIFEST_WINDOWS = 'package.windows.appxmanifest', MANIFEST_PHONE = 'package.phone.appxmanifest', @@ -172,6 +176,13 @@ function applyCoreProperties(config, manifest) { manifest.getVisualElements().setDisplayName(name); } + var description = config.description(); + manifest.getProperties().setDescription(description); + // 'Description' attribute is required for VisualElements node (see + // https://msdn.microsoft.com/en-us/library/windows/apps/br211471.aspx), + // so we set it to '<description>' from config.xml or default value + manifest.getVisualElements().setDescription(description || DEFAULT_DESCRIPTION); + // CB-9410: Get a display name and publisher display name. In the Windows Store, certain // strings which are typically used in Cordova aren't valid for Store ingestion. // Here, we check for Windows-specific preferences, and if we find it, prefer that over --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cordova.apache.org For additional commands, e-mail: commits-h...@cordova.apache.org