|
| 1 | +import { isJsonArray, isJsonObject } from '@angular-devkit/core'; |
| 2 | +import { Rule, SchematicContext, Tree, chain } from '@angular-devkit/schematics'; |
| 3 | +import { updateWorkspace } from '@schematics/angular/utility/workspace'; |
| 4 | + |
| 5 | +import { findStylesheetFiles } from '../../utils/file-utils'; |
| 6 | + |
| 7 | +export default function (): Rule { |
| 8 | + return chain([removeStylesFromConfig(), removeIconFonts(), removeFontStyles(), noticeAddSchematics()]); |
| 9 | +} |
| 10 | + |
| 11 | +function removeStylesFromConfig(): Rule { |
| 12 | + return async (_: Tree, context: SchematicContext) => |
| 13 | + updateWorkspace((workspace) => { |
| 14 | + workspace.projects.forEach((project) => { |
| 15 | + project.targets.forEach((target) => { |
| 16 | + const styles = target.options?.styles; |
| 17 | + |
| 18 | + if (!target.options?.styles || !styles || !isJsonArray(styles)) { |
| 19 | + return; |
| 20 | + } |
| 21 | + |
| 22 | + const stylesToRemove = [ |
| 23 | + 'node_modules/fundamental-styles/dist/icon.css', |
| 24 | + './node_modules/@sap-theming/theming-base-content/content/Base/baseLib/sap_fiori_3/css_variables.css', |
| 25 | + './node_modules/fundamental-styles/dist/theming/sap_fiori_3.css' |
| 26 | + ]; |
| 27 | + |
| 28 | + stylesToRemove.forEach((styleToRemove) => { |
| 29 | + const indexInStylesArray = styles.findIndex( |
| 30 | + (configStyle) => typeof configStyle === 'string' && configStyle === styleToRemove |
| 31 | + ); |
| 32 | + if (indexInStylesArray > -1) { |
| 33 | + styles.splice(indexInStylesArray, 1); |
| 34 | + context.logger.info(`✅️ Removed '${styleToRemove}' style from angular.json`); |
| 35 | + } |
| 36 | + }); |
| 37 | + |
| 38 | + target.options.styles = styles; |
| 39 | + }); |
| 40 | + }); |
| 41 | + }); |
| 42 | +} |
| 43 | + |
| 44 | +function removeIconFonts(): Rule { |
| 45 | + return (tree: Tree, context: SchematicContext) => |
| 46 | + updateWorkspace((workspace) => { |
| 47 | + workspace.projects.forEach((project) => { |
| 48 | + project.targets.forEach((target) => { |
| 49 | + const styles = target.options?.styles; |
| 50 | + |
| 51 | + if (!target.options?.styles || !styles || !isJsonArray(styles)) { |
| 52 | + return; |
| 53 | + } |
| 54 | + |
| 55 | + const iconFonts = ['sap_fiori_3_fonts', 'sap_horizon_fonts']; |
| 56 | + |
| 57 | + iconFonts.forEach((fontFile) => { |
| 58 | + // Remove file |
| 59 | + const fontFileWithPath = `${project.sourceRoot}/theming/${fontFile}.css`; |
| 60 | + if (tree.exists(fontFileWithPath)) { |
| 61 | + tree.delete(fontFileWithPath); |
| 62 | + context.logger.info(`✅️ Removed ${fontFile}.css file.`); |
| 63 | + } |
| 64 | + |
| 65 | + // Remove from config |
| 66 | + const indexInStylesArray = styles.findIndex( |
| 67 | + (style) => isJsonObject(style) && style?.bundleName === `${fontFile}` |
| 68 | + ); |
| 69 | + if (indexInStylesArray > -1) { |
| 70 | + styles.splice(indexInStylesArray, 1); |
| 71 | + context.logger.info(`✅️ Removed '${fontFile}' style from angular.json`); |
| 72 | + } |
| 73 | + }); |
| 74 | + |
| 75 | + target.options.styles = styles; |
| 76 | + }); |
| 77 | + }); |
| 78 | + }); |
| 79 | +} |
| 80 | + |
| 81 | +function removeFontStyles(): Rule { |
| 82 | + return (tree: Tree, context: SchematicContext) => { |
| 83 | + const styleSheets = findStylesheetFiles(tree); |
| 84 | + |
| 85 | + if (styleSheets.length > 0) { |
| 86 | + const FONT_FACE_REGEX = /(@font-face)[\w\s]?{[s\S\W\w]+?(?=\s}\s)?\s?}[\n\s]*/gi; |
| 87 | + |
| 88 | + styleSheets.forEach((styleSheet) => { |
| 89 | + let buffer = tree.read(styleSheet); |
| 90 | + if (!buffer) { |
| 91 | + return; |
| 92 | + } |
| 93 | + |
| 94 | + let contents = buffer.toString(); |
| 95 | + |
| 96 | + if (FONT_FACE_REGEX.test(contents)) { |
| 97 | + const matches = contents |
| 98 | + .match(FONT_FACE_REGEX)! |
| 99 | + .filter((m) => m.match(/~@sap-theming.*\.woff/)?.length); |
| 100 | + |
| 101 | + if (matches.length === 0) { |
| 102 | + return; |
| 103 | + } |
| 104 | + |
| 105 | + matches.forEach((match) => { |
| 106 | + contents = contents.replace(match, ''); |
| 107 | + }); |
| 108 | + |
| 109 | + tree.overwrite(styleSheet, contents); |
| 110 | + context.logger.info(`✅️ Removed font styles from stylesheets.`); |
| 111 | + } |
| 112 | + }); |
| 113 | + } |
| 114 | + |
| 115 | + context.logger.info( |
| 116 | + `⚠️ Notice: If you have imported font styles from @sap-theming, please remove it, since now it is controlled by fundamental-ngx` |
| 117 | + ); |
| 118 | + |
| 119 | + return tree; |
| 120 | + }; |
| 121 | +} |
| 122 | + |
| 123 | +function noticeAddSchematics(): Rule { |
| 124 | + return (_: Tree, context: SchematicContext) => { |
| 125 | + // Unfortunately we cannot run it on our own because ng-update doesn't respect schema so there is no way to get options and pass them further |
| 126 | + context.logger.info(`ℹ️ Now you have to run ng-add schematics once again to set up things in the right way.`); |
| 127 | + }; |
| 128 | +} |
0 commit comments