react-native-navigation
Version:
React Native Navigation - truly native navigation for iOS and Android
300 lines (299 loc) • 10.9 kB
JavaScript
"use strict";
import clone from 'lodash/clone';
import isEqual from 'lodash/isEqual';
import isObject from 'lodash/isObject';
import isArray from 'lodash/isArray';
import isString from 'lodash/isString';
import endsWith from 'lodash/endsWith';
import forEach from 'lodash/forEach';
import has from 'lodash/has';
import { Platform, DynamicColorIOS } from 'react-native';
export class OptionsProcessor {
constructor(store, uniqueIdProvider, optionProcessorsRegistry, colorService, assetService, deprecations) {
this.store = store;
this.uniqueIdProvider = uniqueIdProvider;
this.optionProcessorsRegistry = optionProcessorsRegistry;
this.colorService = colorService;
this.assetService = assetService;
this.deprecations = deprecations;
}
processOptions(commandName, options, props) {
if (options) {
this.processObject(options, clone(options), (key, parentOptions) => {
this.deprecations.onProcessOptions(key, parentOptions, commandName);
this.deprecations.checkForDeprecatedOptions(parentOptions);
}, commandName, props);
}
}
processDefaultOptions(options, commandName) {
this.processObject(options, clone(options), (key, parentOptions) => {
this.deprecations.onProcessDefaultOptions(key, parentOptions);
}, commandName);
}
processObject(objectToProcess, parentOptions, onProcess, commandName, props, parentPath) {
forEach(objectToProcess, (value, key) => {
const objectPath = this.resolveObjectPath(key, parentPath);
this.processWithRegisteredProcessor(key, value, objectToProcess, objectPath, commandName, props);
this.processColor(key, value, objectToProcess);
if (!value) {
return;
}
this.processComponent(key, value, objectToProcess);
this.processImage(key, value, objectToProcess);
this.processButtonsPassProps(key, value);
this.processSearchBar(key, value, objectToProcess);
this.processInterpolation(key, value, objectToProcess);
this.processAnimation(key, value, objectToProcess);
onProcess(key, parentOptions);
const processedValue = objectToProcess[key];
if (!isEqual(key, 'passProps') && (isObject(processedValue) || isArray(processedValue))) {
this.processObject(processedValue, parentOptions, onProcess, commandName, props, objectPath);
}
});
}
resolveObjectPath(key, path) {
if (!path) path = key;else path += `.${key}`;
return path;
}
processColor(key, value, options) {
if ((isEqual(key, 'color') || endsWith(key, 'Color')) && !isEqual(key, 'bkgColor')) {
if (Platform.OS === 'ios') this.processColorIOS(key, value, options);else this.processColorAndroid(key, value, options);
}
}
processColorIOS(key, value, options) {
if (value !== undefined) {
if (value === null) {
options[key] = 'NoColor';
} else if (value instanceof Object) {
if ('semantic' in value) {
options[key] = value;
} else if ('dynamic' in value) {
options[key] = DynamicColorIOS({
light: this.colorService.toNativeColor(value.dynamic.light),
dark: this.colorService.toNativeColor(value.dynamic.dark)
});
} else {
options[key] = DynamicColorIOS({
light: this.colorService.toNativeColor(value.light),
dark: this.colorService.toNativeColor(value.dark)
});
}
} else {
options[key] = this.colorService.toNativeColor(value);
}
}
}
processColorAndroid(key, value, options) {
if (value !== undefined) {
const newColorObj = {
dark: 'NoColor',
light: 'NoColor'
};
if (value === null) {
options[key] = newColorObj;
} else if (value instanceof Object) {
if ('semantic' in value || 'resource_paths' in value) {
options[key] = value;
return;
} else {
for (let keyColor in value) {
newColorObj[keyColor] = this.colorService.toNativeColor(value[keyColor]);
}
options[key] = newColorObj;
}
} else {
let parsedColor = this.colorService.toNativeColor(value);
newColorObj.light = parsedColor;
newColorObj.dark = parsedColor;
options[key] = newColorObj;
}
}
}
processWithRegisteredProcessor(key, value, options, path, commandName, passProps) {
const registeredProcessors = this.optionProcessorsRegistry.getProcessors(path);
if (registeredProcessors) {
registeredProcessors.forEach(processor => {
options[key] = processor(value, commandName, passProps);
});
}
}
processImage(key, value, options) {
if (isEqual(key, 'icon') || isEqual(key, 'image') || endsWith(key, 'Icon') || endsWith(key, 'Image')) {
options[key] = isString(value) ? value : this.assetService.resolveFromRequire(value);
}
}
processButtonsPassProps(key, value) {
if (endsWith(key, 'Buttons')) {
forEach(value, button => {
if (button.passProps && button.id) {
this.store.setPendingProps(button.id, button.passProps);
button.passProps = undefined;
}
});
}
}
processComponent(key, value, options) {
if (isEqual(key, 'component')) {
value.componentId = value.id ? value.id : this.uniqueIdProvider.generate('CustomComponent');
this.store.ensureClassForName(value.name);
if (value.passProps) {
this.store.setPendingProps(value.componentId, value.passProps);
}
options[key].passProps = undefined;
}
}
processSearchBar(key, value, options) {
if (key !== 'searchBar') {
return;
}
const deprecatedSearchBarOptions = {
visible: false,
hideOnScroll: options.searchBarHiddenWhenScrolling ?? false,
hideTopBarOnFocus: options.hideNavBarOnFocusSearchBar ?? false,
obscuresBackgroundDuringPresentation: false,
backgroundColor: options.searchBarBackgroundColor,
tintColor: options.searchBarTintColor,
placeholder: options.searchBarPlaceholder ?? ''
};
if (typeof value === 'boolean') {
// Deprecated
this.deprecations.onProcessOptions(key, options, '');
options[key] = {
...deprecatedSearchBarOptions,
visible: value
};
} else {
options[key] = {
...deprecatedSearchBarOptions,
...value
};
}
}
processInterpolation(key, value, options) {
if (isEqual(key, 'interpolation')) {
if (typeof value === 'string') {
this.deprecations.onProcessOptions(key, options, '');
options[key] = {
type: options[key]
};
}
}
}
processAnimation(key, value, options) {
this.processSetRootAnimation(key, value, options);
this.processPush(key, value, options);
this.processPop(key, value, options);
this.processSetStackRoot(key, value, options);
this.processShowModal(key, value, options);
this.processDismissModal(key, value, options);
}
processSetStackRoot(key, animation, parentOptions) {
if (key !== 'setStackRoot') return;
if (this.isNewStackAnimationApi(animation)) return;
this.convertDeprecatedViewAnimationApiToNewStackAnimationApi(animation, parentOptions);
}
isNewStackAnimationApi(animation) {
return has(animation, 'content') || has(animation, 'topBar') || has(animation, 'bottomTabs');
}
convertDeprecatedViewAnimationApiToNewStackAnimationApi(animation, parentOptions) {
if (!has(animation, 'content.enter') && !has(animation, 'content.exit')) {
parentOptions.setStackRoot = {
content: {
enter: animation
}
};
if (has(animation, 'enabled')) {
parentOptions.setStackRoot.enabled = animation.enabled;
}
if (has(animation, 'waitForRender')) {
parentOptions.setStackRoot.waitForRender = animation.waitForRender;
}
}
}
processPop(key, animation, parentOptions) {
if (key !== 'pop') return;
if (animation.content && !has(animation, 'content.enter') && !has(animation, 'content.exit')) {
parentOptions.pop.content = {
exit: animation.content
};
}
if (animation.topBar && !has(animation, 'topBar.enter') && !has(animation, 'topBar.exit')) {
parentOptions.pop.topBar = {
exit: animation.topBar
};
}
if (animation.bottomTabs && !has(animation, 'bottomTabs.enter') && !has(animation, 'bottomTabs.exit')) {
parentOptions.pop.bottomTabs = {
exit: animation.bottomTabs
};
}
}
processSetRootAnimation(key, animation, parentOptions) {
if (key !== 'setRoot') return;
if (Platform.OS === 'android' && !('enter' in animation)) {
parentOptions.setRoot = {
enter: animation
};
} else if (Platform.OS === 'ios' && 'enter' in animation) {
parentOptions.setRoot = animation;
}
}
processShowModal(key, animation, parentOptions) {
if (key !== 'showModal') return;
if (!('enter' in animation)) {
const elementTransitions = animation.elementTransitions;
const sharedElementTransitions = animation.sharedElementTransitions;
const enter = {
...animation
};
delete enter.sharedElementTransitions;
delete enter.elementTransitions;
parentOptions.showModal = {
enter,
sharedElementTransitions,
elementTransitions
};
}
}
processDismissModal(key, animation, parentOptions) {
if (key !== 'dismissModal') return;
if (!('exit' in animation)) {
const elementTransitions = animation.elementTransitions;
const sharedElementTransitions = animation.sharedElementTransitions;
const exit = {
...animation
};
delete exit.sharedElementTransitions;
delete exit.elementTransitions;
parentOptions.dismissModal = {
exit,
sharedElementTransitions,
elementTransitions
};
}
}
processPush(key, animation, parentOptions) {
if (key !== 'push') return;
if (animation.content && !has(animation, 'content.enter') && !has(animation, 'content.exit')) {
parentOptions.push.content = {
enter: animation.content
};
}
if (animation.topBar && !has(animation, 'topBar.enter') && !has(animation, 'topBar.exit')) {
parentOptions.push.topBar = {
enter: animation.topBar
};
}
if (animation.statusBar && !has(animation, 'statusBar.enter') && !has(animation, 'statusBar.exit')) {
parentOptions.push.statusBar = {
enter: animation.statusBar
};
}
if (animation.bottomTabs && !has(animation, 'bottomTabs.enter') && !has(animation, 'bottomTabs.exit')) {
parentOptions.push.bottomTabs = {
enter: animation.bottomTabs
};
}
}
}
//# sourceMappingURL=OptionsProcessor.js.map