mirror of
https://github.com/apache/cordova-android.git
synced 2025-03-04 00:13:20 +08:00
Features/webp support for splashscreen (#1113)
* - linting - platform independent paths in testing - addes some unittest - remove duplication + add comments - delete webp's if png's added, delete png's if webp' added. - Update bin/templates/cordova/lib/prepare.js Co-authored-by: エリス <erisu@users.noreply.github.com> - fix https://github.com/apache/cordova-plugin-splashscreen/issues/257 webp support for android * revert changes * refactor: use source extension for target in getImageResourcePath * fix(prepare): include more extensions in initial splash-screen resource map * tests(prepare): quick-fix for tests * backward slashes must be changed to forward slashes for fast-glob package. Co-authored-by: Raphael von der Grün <raphinesse@gmail.com>
This commit is contained in:
parent
55feadff05
commit
7428bd3a7f
44
bin/templates/cordova/lib/prepare.js
vendored
44
bin/templates/cordova/lib/prepare.js
vendored
@ -302,11 +302,12 @@ function default_versionCode (version) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getImageResourcePath (resourcesDir, type, density, name, sourceName) {
|
function getImageResourcePath (resourcesDir, type, density, name, sourceName) {
|
||||||
if (/\.9\.png$/.test(sourceName)) {
|
// Use same extension as source with special case for 9-Patch files
|
||||||
name = name.replace(/\.png$/, '.9.png');
|
const ext = sourceName.endsWith('.9.png')
|
||||||
}
|
? '.9.png' : path.extname(sourceName).toLowerCase();
|
||||||
var resourcePath = path.join(resourcesDir, (density ? type + '-' + density : type), name);
|
|
||||||
return resourcePath;
|
const subDir = density ? `${type}-${density}` : type;
|
||||||
|
return path.join(resourcesDir, subDir, name + ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAdaptiveImageResourcePath (resourcesDir, type, density, name, sourceName) {
|
function getAdaptiveImageResourcePath (resourcesDir, type, density, name, sourceName) {
|
||||||
@ -317,6 +318,15 @@ function getAdaptiveImageResourcePath (resourcesDir, type, density, name, source
|
|||||||
return resourcePath;
|
return resourcePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeSplashCleanupMap (projectRoot, resourcesDir) {
|
||||||
|
// Build an initial resource map that deletes all existing splash screens
|
||||||
|
const existingSplashPaths = glob.sync(
|
||||||
|
`${resourcesDir.replace(/\\/g, '/')}/drawable-*/screen.{png,9.png,webp,jpg,jpeg}`,
|
||||||
|
{ cwd: projectRoot }
|
||||||
|
);
|
||||||
|
return makeCleanResourceMap(existingSplashPaths);
|
||||||
|
}
|
||||||
|
|
||||||
function updateSplashes (cordovaProject, platformResourcesDir) {
|
function updateSplashes (cordovaProject, platformResourcesDir) {
|
||||||
var resources = cordovaProject.projectConfig.getSplashScreens('android');
|
var resources = cordovaProject.projectConfig.getSplashScreens('android');
|
||||||
|
|
||||||
@ -326,7 +336,8 @@ function updateSplashes (cordovaProject, platformResourcesDir) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var resourceMap = mapImageResources(cordovaProject.root, platformResourcesDir, 'drawable', 'screen.png');
|
// Build an initial resource map that deletes all existing splash screens
|
||||||
|
const resourceMap = makeSplashCleanupMap(cordovaProject.root, platformResourcesDir);
|
||||||
|
|
||||||
var hadMdpi = false;
|
var hadMdpi = false;
|
||||||
resources.forEach(function (resource) {
|
resources.forEach(function (resource) {
|
||||||
@ -337,14 +348,14 @@ function updateSplashes (cordovaProject, platformResourcesDir) {
|
|||||||
hadMdpi = true;
|
hadMdpi = true;
|
||||||
}
|
}
|
||||||
var targetPath = getImageResourcePath(
|
var targetPath = getImageResourcePath(
|
||||||
platformResourcesDir, 'drawable', resource.density, 'screen.png', path.basename(resource.src));
|
platformResourcesDir, 'drawable', resource.density, 'screen', path.basename(resource.src));
|
||||||
resourceMap[targetPath] = resource.src;
|
resourceMap[targetPath] = resource.src;
|
||||||
});
|
});
|
||||||
|
|
||||||
// There's no "default" drawable, so assume default == mdpi.
|
// There's no "default" drawable, so assume default == mdpi.
|
||||||
if (!hadMdpi && resources.defaultResource) {
|
if (!hadMdpi && resources.defaultResource) {
|
||||||
var targetPath = getImageResourcePath(
|
var targetPath = getImageResourcePath(
|
||||||
platformResourcesDir, 'drawable', 'mdpi', 'screen.png', path.basename(resources.defaultResource.src));
|
platformResourcesDir, 'drawable', 'mdpi', 'screen', path.basename(resources.defaultResource.src));
|
||||||
resourceMap[targetPath] = resources.defaultResource.src;
|
resourceMap[targetPath] = resources.defaultResource.src;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,7 +367,8 @@ function updateSplashes (cordovaProject, platformResourcesDir) {
|
|||||||
function cleanSplashes (projectRoot, projectConfig, platformResourcesDir) {
|
function cleanSplashes (projectRoot, projectConfig, platformResourcesDir) {
|
||||||
var resources = projectConfig.getSplashScreens('android');
|
var resources = projectConfig.getSplashScreens('android');
|
||||||
if (resources.length > 0) {
|
if (resources.length > 0) {
|
||||||
var resourceMap = mapImageResources(projectRoot, platformResourcesDir, 'drawable', 'screen.png');
|
const resourceMap = makeSplashCleanupMap(projectRoot, platformResourcesDir);
|
||||||
|
|
||||||
events.emit('verbose', 'Cleaning splash screens at ' + platformResourcesDir);
|
events.emit('verbose', 'Cleaning splash screens at ' + platformResourcesDir);
|
||||||
|
|
||||||
// No source paths are specified in the map, so updatePaths() will delete the target files.
|
// No source paths are specified in the map, so updatePaths() will delete the target files.
|
||||||
@ -546,13 +558,13 @@ function updateIconResourceForLegacy (preparedIcons, resourceMap, platformResour
|
|||||||
// The source paths for icons and splashes are relative to
|
// The source paths for icons and splashes are relative to
|
||||||
// project's config.xml location, so we use it as base path.
|
// project's config.xml location, so we use it as base path.
|
||||||
for (var density in android_icons) {
|
for (var density in android_icons) {
|
||||||
var targetPath = getImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher.png', path.basename(android_icons[density].src));
|
var targetPath = getImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher', path.basename(android_icons[density].src));
|
||||||
resourceMap[targetPath] = android_icons[density].src;
|
resourceMap[targetPath] = android_icons[density].src;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There's no "default" drawable, so assume default == mdpi.
|
// There's no "default" drawable, so assume default == mdpi.
|
||||||
if (default_icon && !android_icons.mdpi) {
|
if (default_icon && !android_icons.mdpi) {
|
||||||
var defaultTargetPath = getImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher.png', path.basename(default_icon.src));
|
var defaultTargetPath = getImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher', path.basename(default_icon.src));
|
||||||
resourceMap[defaultTargetPath] = default_icon.src;
|
resourceMap[defaultTargetPath] = default_icon.src;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,6 +685,16 @@ function mapImageResources (rootDir, subDir, type, resourceName) {
|
|||||||
return pathMap;
|
return pathMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns resource map that deletes all given paths */
|
||||||
|
function makeCleanResourceMap (resourcePaths) {
|
||||||
|
const pathMap = {};
|
||||||
|
resourcePaths.map(path.normalize)
|
||||||
|
.forEach(resourcePath => {
|
||||||
|
pathMap[resourcePath] = null;
|
||||||
|
});
|
||||||
|
return pathMap;
|
||||||
|
}
|
||||||
|
|
||||||
function updateFileResources (cordovaProject, platformDir) {
|
function updateFileResources (cordovaProject, platformDir) {
|
||||||
var files = cordovaProject.projectConfig.getFileResources('android');
|
var files = cordovaProject.projectConfig.getFileResources('android');
|
||||||
|
|
||||||
|
@ -81,6 +81,18 @@ function mockGetIconItem (data) {
|
|||||||
}, data);
|
}, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a mock item from the getSplashScreen collection with the supplied updated data.
|
||||||
|
*
|
||||||
|
* @param {Object} data Changes to apply to the mock getSplashScreen item
|
||||||
|
*/
|
||||||
|
function mockGetSplashScreenItem (data) {
|
||||||
|
return Object.assign({}, {
|
||||||
|
src: undefined,
|
||||||
|
density: undefined
|
||||||
|
}, data);
|
||||||
|
}
|
||||||
|
|
||||||
describe('prepare', () => {
|
describe('prepare', () => {
|
||||||
describe('updateIcons method', function () {
|
describe('updateIcons method', function () {
|
||||||
// Rewire
|
// Rewire
|
||||||
@ -833,4 +845,129 @@ describe('prepare', () => {
|
|||||||
).toBeResolved();
|
).toBeResolved();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('updateSplashes method', function () {
|
||||||
|
// Rewire
|
||||||
|
let prepare;
|
||||||
|
|
||||||
|
// Spies
|
||||||
|
let emitSpy;
|
||||||
|
let updatePathsSpy;
|
||||||
|
|
||||||
|
// Mock Data
|
||||||
|
let cordovaProject;
|
||||||
|
let platformResourcesDir;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
prepare = rewire('../../bin/templates/cordova/lib/prepare');
|
||||||
|
|
||||||
|
cordovaProject = {
|
||||||
|
root: '/mock',
|
||||||
|
projectConfig: {
|
||||||
|
path: '/mock/config.xml',
|
||||||
|
cdvNamespacePrefix: 'cdv'
|
||||||
|
},
|
||||||
|
locations: {
|
||||||
|
plugins: '/mock/plugins',
|
||||||
|
www: '/mock/www'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
platformResourcesDir = PATH_RESOURCE;
|
||||||
|
|
||||||
|
emitSpy = jasmine.createSpy('emit');
|
||||||
|
prepare.__set__('events', {
|
||||||
|
emit: emitSpy
|
||||||
|
});
|
||||||
|
|
||||||
|
updatePathsSpy = jasmine.createSpy('updatePaths');
|
||||||
|
prepare.__set__('FileUpdater', {
|
||||||
|
updatePaths: updatePathsSpy
|
||||||
|
});
|
||||||
|
|
||||||
|
// mocking initial responses for mapImageResources
|
||||||
|
prepare.__set__('makeSplashCleanupMap', (rootDir, resourcesDir) => ({
|
||||||
|
[path.join(resourcesDir, 'drawable-mdpi/screen.png')]: null,
|
||||||
|
[path.join(resourcesDir, 'drawable-mdpi/screen.webp')]: null
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Test#001 : Should detect no defined splash screens.', function () {
|
||||||
|
const updateSplashes = prepare.__get__('updateSplashes');
|
||||||
|
|
||||||
|
// mock data.
|
||||||
|
cordovaProject.projectConfig.getSplashScreens = function (platform) {
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
updateSplashes(cordovaProject, platformResourcesDir);
|
||||||
|
|
||||||
|
// The emit was called
|
||||||
|
expect(emitSpy).toHaveBeenCalled();
|
||||||
|
|
||||||
|
// The emit message was.
|
||||||
|
const actual = emitSpy.calls.argsFor(0)[1];
|
||||||
|
const expected = 'This app does not have splash screens defined';
|
||||||
|
expect(actual).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Test#02 : Should update splash png icon.', function () {
|
||||||
|
const updateSplashes = prepare.__get__('updateSplashes');
|
||||||
|
|
||||||
|
// mock data.
|
||||||
|
cordovaProject.projectConfig.getSplashScreens = function (platform) {
|
||||||
|
return [mockGetSplashScreenItem({
|
||||||
|
density: 'mdpi',
|
||||||
|
src: 'res/splash/android/mdpi-screen.png'
|
||||||
|
})];
|
||||||
|
};
|
||||||
|
|
||||||
|
updateSplashes(cordovaProject, platformResourcesDir);
|
||||||
|
|
||||||
|
// The emit was called
|
||||||
|
expect(emitSpy).toHaveBeenCalled();
|
||||||
|
|
||||||
|
// The emit message was.
|
||||||
|
const actual = emitSpy.calls.argsFor(0)[1];
|
||||||
|
const expected = 'Updating splash screens at ' + PATH_RESOURCE;
|
||||||
|
expect(actual).toEqual(expected);
|
||||||
|
|
||||||
|
const actualResourceMap = updatePathsSpy.calls.argsFor(0)[0];
|
||||||
|
const expectedResourceMap = {};
|
||||||
|
expectedResourceMap[path.join(PATH_RESOURCE, 'drawable-mdpi', 'screen.png')] = 'res/splash/android/mdpi-screen.png';
|
||||||
|
expectedResourceMap[path.join(PATH_RESOURCE, 'drawable-mdpi', 'screen.webp')] = null;
|
||||||
|
|
||||||
|
expect(actualResourceMap).toEqual(expectedResourceMap);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Test#03 : Should update splash webp icon.', function () {
|
||||||
|
const updateSplashes = prepare.__get__('updateSplashes');
|
||||||
|
|
||||||
|
// mock data.
|
||||||
|
cordovaProject.projectConfig.getSplashScreens = function (platform) {
|
||||||
|
return [mockGetSplashScreenItem({
|
||||||
|
density: 'mdpi',
|
||||||
|
src: 'res/splash/android/mdpi-screen.webp'
|
||||||
|
})];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creating Spies
|
||||||
|
updateSplashes(cordovaProject, platformResourcesDir);
|
||||||
|
|
||||||
|
// The emit was called
|
||||||
|
expect(emitSpy).toHaveBeenCalled();
|
||||||
|
|
||||||
|
// The emit message was.
|
||||||
|
const actual = emitSpy.calls.argsFor(0)[1];
|
||||||
|
const expected = 'Updating splash screens at ' + PATH_RESOURCE;
|
||||||
|
expect(actual).toEqual(expected);
|
||||||
|
|
||||||
|
const actualResourceMap = updatePathsSpy.calls.argsFor(0)[0];
|
||||||
|
|
||||||
|
const expectedResourceMap = {};
|
||||||
|
expectedResourceMap[path.join(PATH_RESOURCE, 'drawable-mdpi', 'screen.webp')] = 'res/splash/android/mdpi-screen.webp';
|
||||||
|
expectedResourceMap[path.join(PATH_RESOURCE, 'drawable-mdpi', 'screen.png')] = null;
|
||||||
|
|
||||||
|
expect(actualResourceMap).toEqual(expectedResourceMap);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user