listable-object.decorator.ts (dspace-angular-dspace-7.0) | : | listable-object.decorator.ts (dspace-angular-dspace-7.1) | ||
---|---|---|---|---|
import { ViewMode } from '../../../../core/shared/view-mode.model'; | import { ViewMode } from '../../../../core/shared/view-mode.model'; | |||
import { Context } from '../../../../core/shared/context.model'; | import { Context } from '../../../../core/shared/context.model'; | |||
import { hasNoValue, hasValue } from '../../../empty.util'; | import { hasNoValue, hasValue, isNotEmpty } from '../../../empty.util'; | |||
import { | ||||
DEFAULT_CONTEXT, | ||||
DEFAULT_THEME | ||||
} from '../../../metadata-representation/metadata-representation.decorator'; | ||||
import { GenericConstructor } from '../../../../core/shared/generic-constructor' ; | import { GenericConstructor } from '../../../../core/shared/generic-constructor' ; | |||
import { ListableObject } from '../listable-object.model'; | import { ListableObject } from '../listable-object.model'; | |||
import { environment } from '../../../../../environments/environment'; | ||||
import { ThemeConfig } from '../../../../../config/theme.model'; | ||||
import { InjectionToken } from '@angular/core'; | ||||
export const DEFAULT_VIEW_MODE = ViewMode.ListElement; | export const DEFAULT_VIEW_MODE = ViewMode.ListElement; | |||
export const DEFAULT_CONTEXT = Context.Any; | ||||
export const DEFAULT_THEME = '*'; | ||||
/** | ||||
* Factory to allow us to inject getThemeConfigFor so we can mock it in tests | ||||
*/ | ||||
export const GET_THEME_CONFIG_FOR_FACTORY = new InjectionToken<(str) => ThemeCon | ||||
fig>('getThemeConfigFor', { | ||||
providedIn: 'root', | ||||
factory: () => getThemeConfigFor | ||||
}); | ||||
const map = new Map(); | const map = new Map(); | |||
/** | /** | |||
* Decorator used for rendering a listable object | * Decorator used for rendering a listable object | |||
* @param objectType The object type or entity type the component represents | * @param objectType The object type or entity type the component represents | |||
* @param viewMode The view mode the component represents | * @param viewMode The view mode the component represents | |||
* @param context The optional context the component represents | * @param context The optional context the component represents | |||
* @param theme The optional theme for the component | * @param theme The optional theme for the component | |||
*/ | */ | |||
skipping to change at line 57 | skipping to change at line 66 | |||
export function getListableObjectComponent(types: (string | GenericConstructor<L istableObject>)[], viewMode: ViewMode, context: Context = DEFAULT_CONTEXT, theme : string = DEFAULT_THEME) { | export function getListableObjectComponent(types: (string | GenericConstructor<L istableObject>)[], viewMode: ViewMode, context: Context = DEFAULT_CONTEXT, theme : string = DEFAULT_THEME) { | |||
let bestMatch; | let bestMatch; | |||
let bestMatchValue = 0; | let bestMatchValue = 0; | |||
for (const type of types) { | for (const type of types) { | |||
const typeMap = map.get(type); | const typeMap = map.get(type); | |||
if (hasValue(typeMap)) { | if (hasValue(typeMap)) { | |||
const typeModeMap = typeMap.get(viewMode); | const typeModeMap = typeMap.get(viewMode); | |||
if (hasValue(typeModeMap)) { | if (hasValue(typeModeMap)) { | |||
const contextMap = typeModeMap.get(context); | const contextMap = typeModeMap.get(context); | |||
if (hasValue(contextMap)) { | if (hasValue(contextMap)) { | |||
if (hasValue(contextMap.get(theme))) { | const match = resolveTheme(contextMap, theme); | |||
return contextMap.get(theme); | if (hasValue(match)) { | |||
return match; | ||||
} | } | |||
if (bestMatchValue < 3 && hasValue(contextMap.get(DEFAULT_THEME))) { | if (bestMatchValue < 3 && hasValue(contextMap.get(DEFAULT_THEME))) { | |||
bestMatchValue = 3; | bestMatchValue = 3; | |||
bestMatch = contextMap.get(DEFAULT_THEME); | bestMatch = contextMap.get(DEFAULT_THEME); | |||
} | } | |||
} | } | |||
if (bestMatchValue < 2 && | if (bestMatchValue < 2 && | |||
hasValue(typeModeMap.get(DEFAULT_CONTEXT)) && | hasValue(typeModeMap.get(DEFAULT_CONTEXT)) && | |||
hasValue(typeModeMap.get(DEFAULT_CONTEXT).get(DEFAULT_THEME))) { | hasValue(typeModeMap.get(DEFAULT_CONTEXT).get(DEFAULT_THEME))) { | |||
bestMatchValue = 2; | bestMatchValue = 2; | |||
skipping to change at line 83 | skipping to change at line 93 | |||
hasValue(typeMap.get(DEFAULT_VIEW_MODE)) && | hasValue(typeMap.get(DEFAULT_VIEW_MODE)) && | |||
hasValue(typeMap.get(DEFAULT_VIEW_MODE).get(DEFAULT_CONTEXT)) && | hasValue(typeMap.get(DEFAULT_VIEW_MODE).get(DEFAULT_CONTEXT)) && | |||
hasValue(typeMap.get(DEFAULT_VIEW_MODE).get(DEFAULT_CONTEXT).get(DEFAULT _THEME))) { | hasValue(typeMap.get(DEFAULT_VIEW_MODE).get(DEFAULT_CONTEXT).get(DEFAULT _THEME))) { | |||
bestMatchValue = 1; | bestMatchValue = 1; | |||
bestMatch = typeMap.get(DEFAULT_VIEW_MODE).get(DEFAULT_CONTEXT).get(DEFA ULT_THEME); | bestMatch = typeMap.get(DEFAULT_VIEW_MODE).get(DEFAULT_CONTEXT).get(DEFA ULT_THEME); | |||
} | } | |||
} | } | |||
} | } | |||
return bestMatch; | return bestMatch; | |||
} | } | |||
/** | ||||
* Searches for a ThemeConfig by its name; | ||||
*/ | ||||
export const getThemeConfigFor = (themeName: string): ThemeConfig => { | ||||
return environment.themes.find(theme => theme.name === themeName); | ||||
}; | ||||
/** | ||||
* Find a match in the given map for the given theme name, taking theme extensio | ||||
n into account | ||||
* | ||||
* @param contextMap A map of theme names to components | ||||
* @param themeName The name of the theme to check | ||||
* @param checkedThemeNames The list of theme names that are already checked | ||||
*/ | ||||
export const resolveTheme = (contextMap: Map<any, any>, themeName: string, check | ||||
edThemeNames: string[] = []): any => { | ||||
const match = contextMap.get(themeName); | ||||
if (hasValue(match)) { | ||||
return match; | ||||
} else { | ||||
const cfg = getThemeConfigFor(themeName); | ||||
if (hasValue(cfg) && isNotEmpty(cfg.extends)) { | ||||
const nextTheme = cfg.extends; | ||||
const nextCheckedThemeNames = [...checkedThemeNames, themeName]; | ||||
if (checkedThemeNames.includes(nextTheme)) { | ||||
throw new Error('Theme extension cycle detected: ' + [...nextCheckedThem | ||||
eNames, nextTheme].join(' -> ')); | ||||
} else { | ||||
return resolveTheme(contextMap, nextTheme, nextCheckedThemeNames); | ||||
} | ||||
} | ||||
} | ||||
}; | ||||
End of changes. 5 change blocks. | ||||
7 lines changed or deleted | 18 lines changed or added |