UNPKG

jqwidgets-ng

Version:

[![Price](https://img.shields.io/badge/price-COMMERCIAL-0098f7.svg)](https://jqwidgets.com/license/)

180 lines (176 loc) 9.9 kB
"use strict"; /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.addTypographyClass = exports.addThemeToAppStyles = void 0; const core_1 = require("@angular-devkit/core"); const schematics_1 = require("@angular-devkit/schematics"); const schematics_2 = require("jqwidgets-ng/schematics/cdk/schematics"); const change_1 = require("@schematics/angular/utility/change"); const workspace_1 = require("@schematics/angular/utility/workspace"); const path_1 = require("path"); const create_custom_theme_1 = require("./create-custom-theme"); /** Path segment that can be found in paths that refer to a prebuilt theme. */ let prebuiltThemePathSegment = 'jqwidgets-ng/jqwidgets/styles'; /** Default file name of the custom theme that can be generated. */ const defaultCustomThemeFilename = 'custom-theme.scss'; /** Add pre-built styles to the main project style file. */ function addThemeToAppStyles(options) { return (host, context) => { const themeName = options.theme || 'base'; return themeName === 'custom' ? insertCustomTheme(options.project, host, context.logger) : insertPrebuiltTheme(options.project, 'jqx.' + themeName, context.logger); }; } exports.addThemeToAppStyles = addThemeToAppStyles; /** Adds the global typography class to the body element. */ function addTypographyClass(options) { return (host) => __awaiter(this, void 0, void 0, function* () { const workspace = yield workspace_1.getWorkspace(host); const project = schematics_2.getProjectFromWorkspace(workspace, options.project); const projectIndexFiles = schematics_2.getProjectIndexFiles(project); if (!projectIndexFiles.length) { throw new schematics_1.SchematicsException('No project index HTML file could be found.'); } if (options.typography) { projectIndexFiles.forEach(path => schematics_2.addBodyClass(host, path, 'mat-typography')); } }); } exports.addTypographyClass = addTypographyClass; /** * Insert a custom theme to project style file. If no valid style file could be found, a new * Scss file for the custom theme will be created. */ function insertCustomTheme(projectName, host, logger) { return __awaiter(this, void 0, void 0, function* () { const workspace = yield workspace_1.getWorkspace(host); const project = schematics_2.getProjectFromWorkspace(workspace, projectName); const stylesPath = schematics_2.getProjectStyleFile(project, 'scss'); const themeContent = create_custom_theme_1.createCustomTheme(projectName); if (!stylesPath) { if (!project.sourceRoot) { throw new schematics_1.SchematicsException(`Could not find source root for project: "${projectName}". ` + `Please make sure that the "sourceRoot" property is set in the workspace config.`); } // Normalize the path through the devkit utilities because we want to avoid having // unnecessary path segments and windows backslash delimiters. const customThemePath = core_1.normalize(path_1.join(project.sourceRoot, defaultCustomThemeFilename)); if (host.exists(customThemePath)) { logger.warn(`Cannot create a custom Angular Material theme because ${customThemePath} already exists. Skipping custom theme generation.`); return schematics_1.noop(); } host.create(customThemePath, themeContent); return addThemeStyleToTarget(projectName, 'build', customThemePath, logger); } const insertion = new change_1.InsertChange(stylesPath, 0, themeContent); const recorder = host.beginUpdate(stylesPath); recorder.insertLeft(insertion.pos, insertion.toAdd); host.commitUpdate(recorder); return schematics_1.noop(); }); } /** Insert a pre-built theme into the angular.json file. */ function insertPrebuiltTheme(project, theme, logger) { // Path needs to be always relative to the `package.json` or workspace root. const baseThemePath = `./node_modules/jqwidgets-ng/jqwidgets/styles/jqx.base.css`; const themePath = `./node_modules/jqwidgets-ng/jqwidgets/styles/${theme}.css`; if (theme === 'jqx.base') { return schematics_1.chain([ addThemeStyleToTarget(project, 'build', themePath, logger), addThemeStyleToTarget(project, 'test', themePath, logger) ]); } else { prebuiltThemePathSegment += "/" + theme; return schematics_1.chain([ addThemeStyleToTarget(project, 'build', baseThemePath, logger), addThemeStyleToTarget(project, 'test', baseThemePath, logger), addThemeStyleToTarget(project, 'build', themePath, logger), addThemeStyleToTarget(project, 'test', themePath, logger) ]); } } /** Adds a theming style entry to the given project target options. */ function addThemeStyleToTarget(projectName, targetName, assetPath, logger) { return workspace_1.updateWorkspace(workspace => { const project = schematics_2.getProjectFromWorkspace(workspace, projectName); // Do not update the builder options in case the target does not use the default CLI builder. if (!validateDefaultTargetBuilder(project, targetName, logger)) { return; } const targetOptions = schematics_2.getProjectTargetOptions(project, targetName); const styles = targetOptions.styles; if (!styles) { targetOptions.styles = [assetPath]; } else { const existingStyles = styles.map(s => typeof s === 'string' ? s : s.input); for (let [index, stylePath] of existingStyles.entries()) { // If the given asset is already specified in the styles, we don't need to do anything. if (stylePath === assetPath) { return; } // In case a prebuilt theme is already set up, we can safely replace the theme with the new // theme file. If a custom theme is set up, we are not able to safely replace the custom // theme because these files can contain custom styles, while prebuilt themes are // always packaged and considered replaceable. if (stylePath.includes(defaultCustomThemeFilename)) { logger.error(`Could not add the selected theme to the CLI project ` + `configuration because there is already a custom theme file referenced.`); logger.info(`Please manually add the following style file to your configuration:`); logger.info(` ${assetPath}`); return; } else if (stylePath.includes(prebuiltThemePathSegment)) { styles.splice(index, 1); } } styles.push(assetPath); } }); } /** * Validates that the specified project target is configured with the default builders which are * provided by the Angular CLI. If the configured builder does not match the default builder, * this function can either throw or just show a warning. */ function validateDefaultTargetBuilder(project, targetName, logger) { const defaultBuilder = schematics_2.defaultTargetBuilders[targetName]; const targetConfig = project.targets && project.targets.get(targetName); const isDefaultBuilder = targetConfig && targetConfig['builder'] === defaultBuilder; // Because the build setup for the Angular CLI can be customized by developers, we can't know // where to put the theme file in the workspace configuration if custom builders are being // used. In case the builder has been changed for the "build" target, we throw an error and // exit because setting up a theme is a primary goal of `ng-add`. Otherwise if just the "test" // builder has been changed, we warn because a theme is not mandatory for running tests // with Material. See: https://github.com/angular/components/issues/14176 if (!isDefaultBuilder && targetName === 'build') { throw new schematics_1.SchematicsException(`Your project is not using the default builders for ` + `"${targetName}". The Angular Material schematics cannot add a theme to the workspace ` + `configuration if the builder has been changed.`); } else if (!isDefaultBuilder) { // for non-build targets we gracefully report the error without actually aborting the // setup schematic. This is because a theme is not mandatory for running tests. logger.warn(`Your project is not using the default builders for "${targetName}". This ` + `means that we cannot add the configured theme to the "${targetName}" target.`); } return isDefaultBuilder; }