diff --git a/.eslintrc.js b/.eslintrc.js index 98583890..8620c749 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,7 +3,7 @@ module.exports = { browser: true, es2021: true }, - ignorePatterns: ['js/lib', 'node_modules', 'wwwroot/js/*.min.js', 'input/assets/js/*.min.js', 'Scripts/*.min.js'], + ignorePatterns: ['js/src/lib', 'node_modules', 'wwwroot/js/*.min.js', 'input/assets/js/*.min.js', 'Scripts/*.min.js'], globals: { Prism: 'readonly' }, @@ -14,7 +14,7 @@ module.exports = { }, overrides: [ { - files: ['js/ts/**/*.ts', 'playwright/**/*.ts'], + files: ['js/src/ts/**/*.ts', 'playwright/**/*.ts', 'build/**/*.ts'], extends: [ 'standard', 'eslint:recommended', @@ -42,7 +42,7 @@ module.exports = { } }, { - files: ['.eslintrc.js', 'js/**/*.*', 'getting-started/*.js', 'playwright/**/*.ts', 'wwwroot/js/src/**/*.js', 'gulpfile.js'], + files: ['.eslintrc.js', 'postcss.config.js', 'js/**/**/*.*', 'getting-started/*.js', 'playwright/**/*.ts', 'wwwroot/js/src/**/*.js', 'build/**/*.*'], rules: { semi: ['error', 'always'], quotes: ['error', 'single'], @@ -55,6 +55,7 @@ module.exports = { 'prefer-arrow-callback': ['error'], 'func-style': ['error', 'expression'], 'arrow-parens': ['error', 'as-needed'], + 'object-shorthand': ['error', 'consistent-as-needed'], eqeqeq: 0 } } diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index e589bf60..c39a1437 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -7,6 +7,6 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 20 - run: yarn - - run: yarn run eslint js/**/**/*.{js,ts} + - run: yarn run eslint js/**/*.{js,ts} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9fb1657e..3da66f58 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -11,7 +11,7 @@ jobs: # Setup .npmrc file to publish to npm - uses: actions/setup-node@v3 with: - node-version: '18' + node-version: '20' registry-url: 'https://registry.npmjs.org' # Defaults to the user or organization that owns the workflow file scope: '@chocolatey-software' diff --git a/.github/workflows/stylelint.yaml b/.github/workflows/stylelint.yaml index 7d31b39a..5cb9cdb0 100644 --- a/.github/workflows/stylelint.yaml +++ b/.github/workflows/stylelint.yaml @@ -7,6 +7,6 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 20 - run: yarn - - run: yarn run stylelint "scss/**/**/*.scss" + - run: yarn run stylelint "scss/**/*.scss" diff --git a/.gitignore b/.gitignore index abf39e75..9e21348e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ package-lock.json -.DS_Store \ No newline at end of file +.DS_Store +.cache/ \ No newline at end of file diff --git a/.stylelintignore b/.stylelintignore index d6634351..9758a718 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -1,3 +1,2 @@ -scss/_atcb.scss scss/_datatables.scss scss/_prism.scss diff --git a/.stylelintrc.json b/.stylelintrc.json index 854de66a..d5a00173 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -4,7 +4,7 @@ ], "rules": { "scss/selector-no-union-class-name": true, - "indentation": 4, + "@stylistic/indentation": 4, "selector-max-id" : 20, "selector-max-class" : 20, "selector-max-compound-selectors": 20, diff --git a/.vscode/settings.json b/.vscode/settings.json index 7eb99011..0f91b72c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,17 +9,28 @@ "choco", "chocolateyfest", "Chocolatiers", + "combinators", + "cssnano", "datatables", "DOCSEARCH", + "easymde", + "favicons", "fileupload", "Flatpickr", + "fontawesome", + "fortawesome", "globalnavigation", "lazyload", "livestream", "Livestreams", "Luxon", "navigations", + "nouislider", "offcanvas", + "outdir", + "popperjs", + "prismjs", + "purgecss", "scrollspy", "searchbox", "socialmedia", @@ -27,8 +38,11 @@ "splidejs", "stylelint", "svgstyles", + "tarekraafat", "textbox", "topnav", - "typeahead" + "typeahead", + "webfonts", + "xmark" ] } \ No newline at end of file diff --git a/README.md b/README.md index 764719b8..a41af830 100644 --- a/README.md +++ b/README.md @@ -1,141 +1,29 @@ -# Chocolatey choco-theme +# Chocolatey choco-theme 0.6.0 **NOTE: This project is used on Chocolatey websites and is being released for the benefit of the community. While we endeavour to help and fix issues, it will be limited to GitHub issues, discussions and pull requests when we are able to.** This repository holds all of the CSS, JS, images, and shared partial files that are used across many Chocolatey projects. -## Getting Started +## Commands -### Step 1: Setup Yarn +Before running any commands below, ensure you have ran `yarn` in the root of this repository, and have enabled corepack by running `corepack enable`. -#### Install Yarn +| Script | Action | +|-----------------------------------------|----------------------------------------------------------------------------------------| +| build | Builds CSS, JS, and Partials. | +| lint | Runs Stylelint and ESLint to determine code style errors. | +| release OLD_VERSION NEW_VERSION | Runs all build steps and updates choco-theme to the version specified. | +| watch | Watches for changes in CSS, JS, and Partials, and rebuilds them automatically. | -Navigate to the root of your repository where you want the `node_modules` folder to be installed. Follow the directions at the below links: +## Install ESLint Extension -1. https://yarnpkg.com/getting-started/install#install-corepack -1. https://yarnpkg.com/getting-started/install#initializing-your-project +In order to see ESLint errors while in the source code, ensure that you have installed and enabled an [ESLint Extension](https://eslint.org/docs/latest/use/integrations) for your editor. -A new `package.json` and `.yarnrc.yml` file will be generated after the above steps are complete. +## Install Stylelint Extension -#### Modify `.yarnrc.yml` File +In order to see Stylelint errors while in the source code, ensure that you have installed and enabled a [Stylelint Extension](https://stylelint.io/awesome-stylelint/#editor-integrations) for your editor. -In the newly generated `.yarnrc.yml` file, copy the following lines to the end of the document: - -``` -nodeLinker: node-modules -checksumBehavior: "update" -``` - -#### Modify `package.json` File - -In the choco-theme repository, navigate to `getting-started/_package.json`, and copy the contents into the new `package.json` file that was just created in your project. - -* Be sure not to change lines 2 and 3, as these are specific to your new project. -* Update the git information in the package.json file in your new project to the correct information. - -#### Update `.gitignore` File - -Add the following lines to the `.gitignore` file in your repository. Any file path containing `input` may need updated to your specific repository folder structure. - -``` -input/assets/css/ -input/assets/js/ -input/assets/fonts/ -input/assets/images/global-shared/ -input/global-partials/ -apple-touch-*.png -favicon.ico -node_modules/ -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/sdks -!.yarn/versions -``` - -### Step 2: Setup Gulp - -#### Copy `gulpfile.js` File Into Your Repository - -In the choco-theme repository, navigate to `getting-started/_gulpfile.js`, and copy the file into your new repository in the same directory as the `package.json` file. Change the name to `gulpfile.js`. - -Depending on the new project setup, the variable paths in `gulpfile.js` may need updated. There is a block in `gulpfile.js` that should look similar to below: - -``` -const paths = { - input: 'input/', - assets: 'input/assets/', - partials: 'input/global-partials', - node_modules: 'node_modules/', - theme: 'node_modules/choco-theme/' -}; -``` - -#### Copy `bundleconfig.json` File Into Your Repository - -In the choco-theme repository, navigate to `getting-started/_bundleconfig.json`, and copy the file into your new repository in the same directory as the `package.json` file. Change the name to `bundleconfig.json`. - -In the bundle named `input/assets/js/chocolatey.bundle.js` you will need to modify the input file name to match the name of your project. Replace the `${projectName}` variable. - -#### Create a New JavaScript File - -In choco-theme, you will need to copy a file inside of `js/init` into the same folder and name it according to the project name, and the name that you chose for the `bundleconfig.json` file's input path in the step above. - -At this point, an informed decision will need to be made about what JavaScript files from choco-theme need to be included in the project. - -### Step 3: Run It! - -#### Yarn - -From the command line in the root of your repository where the `package.json` file is located, run the command: - -``` -yarn -``` - -This will generate the `node_modules` folder an install any dependencies. - -#### Gulp - -From the command line in the root of your repository where the `package.json` file is located, run the command: - -``` -gulp -``` - -This will generate all the CSS and JS and place images and global partials in the correct folders. - -#### Include Assets in HTML - -Directly before the closing `` tag in your HTML document, include the following lines: - -``` - - -``` - -Directly before the closing `` tag in your HTML document, include the following lines: - -``` - - -``` - -File paths may need to be updated based on your project structure. - -Given that everything succeeded, choco-theme is set up and ready to go! - -## ESLint -To run ESLint on a file or folder, run the following command `yarn run eslint js/filename.js`. Visit the [ESLint documentation](https://eslint.org/docs/latest/user-guide/getting-started#installation-and-usage) for more information. - -## Sytlelint -To run Stylelint on a file or folder, run the following command `yarn run stylelint "scss/filename.scss"`. Visit the [Stylelint documentation](https://stylelint.io/) for more information. - -## What's Included - -### External Libraries +## External Libraries Choco-theme contains many external libraries in which it depends on for various features. @@ -146,7 +34,7 @@ Choco-theme contains many external libraries in which it depends on for various | :heavy_minus_sign: | Not used. | | :grey_question: | May or may not be used. Project may be under development. | -| External Libraries | chocolatey.org | community | docs | blog | design | company | chocolateyfest.com | boxstarter.org | zendesk | +| External Libraries | org | community | docs | blog | design | portal | fest | boxstarter | zendesk | |-------------------------------|--------------------|--------------------|--------------------|--------------------|--------------------|--------------------|--------------------|--------------------| -------------------| | jQuery | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_minus_sign: | :heavy_check_mark: | :heavy_check_mark: | :heavy_minus_sign: | :heavy_check_mark: | :heavy_minus_sign: | | Bootstrap | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | diff --git a/build/build-partials.ts b/build/build-partials.ts new file mode 100644 index 00000000..51ab6c9a --- /dev/null +++ b/build/build-partials.ts @@ -0,0 +1,128 @@ +#!/usr/bin/env ts-node + +/*! + * Script to build partials. + * Copyright 2020-2024 Chocolatey Software + * Licensed under Apache License (https://github.com/chocolatey/choco-theme/blob/main/LICENSE) + */ + +import * as fs from 'fs/promises'; +import path from 'node:path'; +import { updateContent } from './functions/update-content'; + +export interface UpdateLanguageAttributes { + files: string[]; + destination: string; + newExt: string; +} + +const updateLanguageAttributes = async ({ + files, + destination, + newExt +}: UpdateLanguageAttributes): Promise => { + for await (const file of files) { + const oldExt = path.extname(file); + + if (oldExt !== newExt) { + let newFileName = path.basename(file, oldExt); + + if (newExt === '.cshtml') { + newFileName = `_${newFileName}`; + } + + if (newExt === '.hbs') { + newFileName = newFileName.toLowerCase(); + + // Add partial front matter + await updateContent({ + destination: destination, + targetFile: file, + targetFileDestination: destination, + targetFileContentToReplace: null, + replaceWithContent: file, + replacementContentIsFile: true, + replacementTemplate: `---\npartial: ${newFileName}\n---\n{0}` + }); + } + + await fs.rename(path.join(destination, file), path.join(destination, `${newFileName}${newExt}`)); + } + } +}; + +const init = async () => { + try { + console.log('🚀 Building partials...'); + + const destinationTemp = './dist/partials/temp'; + const destinationCshtml = './dist/partials/cshtml'; + const destinationHbs = './dist/partials/hbs'; + + await fs.cp('./partials/', destinationTemp, { recursive: true }); + + // Update GlobalNavigation.html + await updateContent({ + destination: destinationTemp, + targetFile: 'GlobalNavigation.html', + targetFileDestination: destinationTemp, + targetFileContentToReplace: '', + replaceWithContent: 'ThemeToggle.html', + replacementContentIsFile: true + }); + + await fs.cp(destinationTemp, destinationCshtml, { recursive: true }); + await fs.cp(destinationTemp, destinationHbs, { recursive: true }); + await fs.rm(destinationTemp, { recursive: true }); + + // hbs files + await updateContent({ + destination: destinationHbs, + targetFile: 'SocialMedia.html', + targetFileDestination: destinationHbs, + targetFileContentToReplace: '@@chocolatey', + replaceWithContent: '@chocolatey', + replacementContentIsFile: false + }); + + // Delete TopAlertBanner.html + await fs.rm(path.join(destinationHbs, 'TopAlertBanner.html')); + + // cshtml files + await updateContent({ + destination: destinationCshtml, + targetFile: 'TopAlertBanner.html', + targetFileDestination: destinationCshtml, + targetFileContentToReplace: 'topNoticeText = ""', + replaceWithContent: 'AlertText.html', + replacementContentIsFile: true, + replacementTemplate: 'topNoticeText = "{0}"' + }); + + // Delete AlertText.html + await fs.rm(path.join(destinationHbs, 'AlertText.html')); + await fs.rm(path.join(destinationCshtml, 'AlertText.html')); + + // Update file extensions and casing of names + const filesHbs = await fs.readdir(destinationHbs); + const filesCshtml = await fs.readdir(destinationCshtml); + + await updateLanguageAttributes({ + files: filesHbs, + destination: destinationHbs, + newExt: '.hbs' + }); + + await updateLanguageAttributes({ + files: filesCshtml, + destination: destinationCshtml, + newExt: '.cshtml' + }); + + console.log('✅ Partials built'); + } catch (error) { + console.error(error); + } +}; + +init(); diff --git a/build/build-portal.ts b/build/build-portal.ts new file mode 100644 index 00000000..ffbdb97e --- /dev/null +++ b/build/build-portal.ts @@ -0,0 +1,35 @@ +#!/usr/bin/env ts-node + +/*! + * Script to build additional assets for portal. + * Copyright 2020-2024 Chocolatey Software + * Licensed under Apache License (https://github.com/chocolatey/choco-theme/blob/main/LICENSE) + */ + +import * as esbuild from 'esbuild'; +import { purgeCss } from './functions/purge-css'; +import { repositoryConfig } from './data/repository-config'; + +const init = async () => { + console.log('🚀 Compiling and minifying Portal JS...'); + const repository = repositoryConfig.portal; + + await esbuild.build({ + entryPoints: [`${repository.js}src/*.js`], + target: 'es2015', + bundle: true, + outdir: repository.js, + minify: true, + outExtension: { '.js': '.min.js' } + }).then(async () => { + console.log('✅ Portal JS compiled and minified'); + + // PurgeCSS + await purgeCss({ + source: `${repository.css}${repository.name}.min.css`, + repository: repository + }); + }); +}; + +init(); diff --git a/build/change-version.ts b/build/change-version.ts new file mode 100644 index 00000000..b05b1717 --- /dev/null +++ b/build/change-version.ts @@ -0,0 +1,75 @@ +#!/usr/bin/env ts-node + +/*! + * Script to update version number references in the project. + * Copyright 2020-2024 Chocolatey Software + * Licensed under Apache License (https://github.com/chocolatey/choco-theme/blob/main/LICENSE) + */ + +import * as fs from 'fs/promises'; +import * as process from 'process'; + +// These are the files we only care about replacing the version +const FILES: string[] = [ + 'README.md', + 'package.json', + 'scss/mixins/_banner.scss', + 'build/esbuild.ts' +]; + +// Blame TC39... https://github.com/benjamingr/RegExp.escape/issues/37 +const regExpQuote = (string: string): string => string.replace(/[$()*+-.?[\\\]^{|}]/g, '\\$&'); +const regExpQuoteReplacement = (string: string): string => string.replace(/\$/g, '$$'); + +const replaceRecursively = async (file: string, oldVersion: string, newVersion: string): Promise => { + const originalString: string = await fs.readFile(file, 'utf-8'); + const newString: string = originalString + .replace( + new RegExp(regExpQuote(oldVersion), 'g'), + regExpQuoteReplacement(newVersion) + ); + + // No need to move any further if the strings are identical + if (originalString === newString) { + return; + } + + await fs.writeFile(file, newString, 'utf-8'); +}; + +const showUsage = (args: string[]): void => { + console.error('USAGE: change-version old_version new_version'); + console.error('Got arguments:', args); + process.exit(1); +}; + +const init = async (args: string[]): Promise => { + let [oldVersion, newVersion] = args; + + if (!oldVersion || !newVersion) { + showUsage(args); + } + + // Strip any leading `v` from arguments because + // otherwise we will end up with duplicate `v`s + [oldVersion, newVersion] = [oldVersion, newVersion].map(arg => { + return arg.startsWith('v') ? arg.slice(1) : arg; + }); + + if (oldVersion === newVersion) { + showUsage(args); + } + + try { + console.log(`🚀 Changing version from ${oldVersion} to ${newVersion}...`); + await Promise.all( + FILES.map(file => replaceRecursively(file, oldVersion, newVersion)) + ); + console.log('✅ Version changed'); + } catch (error) { + console.error(error); + process.exit(1); + } +}; + +init(process.argv.slice(2)); diff --git a/build/choco-theme.ts b/build/choco-theme.ts new file mode 100644 index 00000000..12291ad7 --- /dev/null +++ b/build/choco-theme.ts @@ -0,0 +1,287 @@ +#!/usr/bin/env ts-node + +/*! + * Script to copy assets and set up choco-theme on an external website. + * Copyright 2020-2024 Chocolatey Software + * Licensed under Apache License (https://github.com/chocolatey/choco-theme/blob/main/LICENSE) + */ + +import * as fs from 'fs/promises'; +import * as process from 'process'; +import { repositoryConfig } from './data/repository-config'; +import { purgeCss } from './functions/purge-css'; +import { updateContent } from './functions/update-content'; + +// Process args +const params: Record = {}; +process.argv.slice(2).forEach(val => { + const [key, value] = val.split('='); + + if (key.startsWith('--')) { + params[key.slice(2)] = value; + } +}); + +// Determine repository information +let repository = repositoryConfig.default; +if (params.repository && repositoryConfig[params.repository]) { + repository = repositoryConfig[params.repository]; + console.log('Using repository information:', repository); +} + +// Determine source CSS name +let sourceCss: string; +switch (repository.name) { + case repositoryConfig.zendesk.name: + case repositoryConfig.boxstarter.name: + sourceCss = repository.name; + break; + default: + sourceCss = 'chocolatey'; + break; +} + +interface CopyTheme { + task: string; + source: string; + destination: string; + isFolder?: boolean; +} + +const copyTheme = async ({ + task, + source, + destination, + isFolder = true +}: CopyTheme): Promise => { + // Clean destination + if (destination !== repository.favicons) { + await fs.rm(destination, { force: true, recursive: isFolder }); + } + + // Copy theme + await fs.cp(source, destination, { recursive: isFolder }); + + console.log(`✅ ${task} copied`); +}; + +const init = async () => { + try { + const containsValidation = repository.name === repositoryConfig.portal.name || repository.name === repositoryConfig.community.name; + + // Define arrays for parallel tasks + const parallelTasksInitial = [ + { + task: 'theme-toggle.min.js', + source: `${repositoryConfig.theme.js}theme-toggle.min.js`, + destination: `${repository.js}theme-toggle.min.js`, + isFolder: false + }, + { + task: `${repository.name}.min.js`, + source: `${repositoryConfig.theme.js}${repository.name}.min.js`, + destination: `${repository.js}${repository.name}.min.js`, + isFolder: false + }, + { + task: 'Partials', + source: `${repositoryConfig.theme.partials}${repository.language}/`, + destination: repository.partials + }, + { + task: `${repository.name}.min.css`, + source: `${repositoryConfig.theme.css}${sourceCss}.min.css`, + destination: `${repository.css}${repository.name}.min.css`, + isFolder: false + } + ]; + + // Conditional tasks + // Community only scripts + if (repository.name === repositoryConfig.community.name) { + parallelTasksInitial.push( + { + task: 'community-packages.min.js', + source: `${repositoryConfig.theme.js}community-packages.min.js`, + destination: `${repository.js}community-packages.min.js`, + isFolder: false + }, + { + task: 'community-package-differ.min.js', + source: `${repositoryConfig.theme.js}community-package-differ.js`, + destination: `${repository.js}community-package-differ.min.js`, + isFolder: false + }, + { + task: 'community-package-stats.min.js', + source: `${repositoryConfig.theme.js}community-package-stats.js`, + destination: `${repository.js}community-package-stats.min.js`, + isFolder: false + } + ); + } + + // Playwright + if (repository.playwright) { + parallelTasksInitial.push( + { + task: 'playwright.config.ts', + source: `${repositoryConfig.theme.root}playwright.config.ts`, + destination: `${repository.root}playwright.config.ts`, + isFolder: false + } + ); + + if (repository.name === repositoryConfig.org.name) { + parallelTasksInitial.push( + { + task: 'Playwright tests', + source: `${repositoryConfig.theme.playwright}tests/pricing-calculator/`, + destination: `${repository.playwright}pricing-calculator/` + } + ); + } + } + + // Favicons + if (repository.name !== repositoryConfig.boxstarter.name) { + parallelTasksInitial.push( + { + task: 'Favicons', + source: repositoryConfig.theme.favicons, + destination: repository.favicons + } + ); + } + + // Font Awesome + if (repository.name !== repositoryConfig.zendesk.name) { + parallelTasksInitial.push( + { + task: 'Font Awesome', + source: repositoryConfig.theme.fontAwesome, + destination: repository.fontAwesome + } + ); + } + + // Images + if (repository.name !== repositoryConfig.zendesk.name) { + parallelTasksInitial.push( + { + task: 'Images', + source: repositoryConfig.theme.images, + destination: repository.images + } + ); + } + + // ESLint and tsconfig - needed if repository contains it's own assets along with choco-theme + if (repository.playwright || repository.name === repositoryConfig.portal.name) { + parallelTasksInitial.push( + { + task: '.eslintrc.js', + source: `${repositoryConfig.theme.root}.eslintrc.js`, + destination: `${repository.root}.eslintrc.js`, + isFolder: false + }, + { + task: 'tsconfig.json', + source: `${repositoryConfig.theme.root}tsconfig.json`, + destination: `${repository.root}tsconfig.json`, + isFolder: false + } + ); + } + + // Validation + if (containsValidation) { + parallelTasksInitial.push( + { + task: 'validation.min.js', + source: `${repositoryConfig.theme.js}validation.min.js`, + destination: `${repository.js}validation.min.js`, + isFolder: false + } + ); + } + + // Execute initial tasks in parallel + console.log('🚀 Starting choco-theme...'); + console.log('🚀 Copying choco-theme...'); + await Promise.all(parallelTasksInitial.map(({ task, source, destination, isFolder }) => { + return copyTheme({ task, source, destination, isFolder }); + })); + console.log('✅ Copying of choco-theme complete'); + + // If blog repository, update Program.cs + if (repository.name === repositoryConfig.blog.name) { + console.log('🚀 Updating Program.cs with AlertText.html...'); + await updateContent({ + destination: `${repositoryConfig.theme.root}partials/`, + targetFile: 'Program.cs', + targetFileDestination: repository.root, + targetFileContentToReplace: '"TopNoticeText", ""', + replaceWithContent: 'AlertText.html', + replacementContentIsFile: true, + replacementTemplate: '"TopNoticeText", "{0}"' + }); + console.log('✅ Program.cs updated'); + } + + // Change CSS content + // Font Awesome + if (repository.name === repositoryConfig.portal.name) { + console.log('🚀 Updating Font Awesome font path...'); + await updateContent({ + destination: repository.css, + targetFile: `${repository.name}.min.css`, + targetFileDestination: repository.css, + targetFileContentToReplace: '/assets/fonts/fontawesome-free', + replaceWithContent: '/fonts/fontawesome-free', + replacementContentIsFile: false + }); + console.log('✅ Font Awesome font path updated'); + } + + if (repository.name === repositoryConfig.community.name) { + // Font Awesome + console.log('🚀 Updating Font Awesome font path...'); + await updateContent({ + destination: repository.css, + targetFile: `${repository.name}.min.css`, + targetFileDestination: repository.css, + targetFileContentToReplace: '/assets/fonts/fontawesome-free', + replaceWithContent: '/Content/fonts/fontawesome-free', + replacementContentIsFile: false + }); + console.log('✅ Font Awesome font path updated'); + + // Images for headers + console.log('🚀 Updating image paths for headers...'); + await updateContent({ + destination: repository.css, + targetFile: `${repository.name}.min.css`, + targetFileDestination: repository.css, + targetFileContentToReplace: '/assets/images', + replaceWithContent: '/Content/images', + replacementContentIsFile: false + }); + console.log('✅ Image paths for headers updated'); + } + + // PurgeCSS + if (repository.name !== repositoryConfig.portal.name) { + await purgeCss({ + source: `${repository.css}${repository.name}.min.css`, + repository: repository + }); + } + + console.log('🎉 choco-theme complete'); + } catch (error) { + console.error(error); + } +}; + +init(); diff --git a/build/data/repository-config.ts b/build/data/repository-config.ts new file mode 100644 index 00000000..17d6aeed --- /dev/null +++ b/build/data/repository-config.ts @@ -0,0 +1,206 @@ +#!/usr/bin/env ts-node + +/*! + * Configuration for repositories. + * Copyright 2020-2024 Chocolatey Software + * Licensed under Apache License (https://github.com/chocolatey/choco-theme/blob/main/LICENSE) + */ + +export interface RepositoryConfig { + name: string; + css: string; + js: string; + favicons: string; + fontAwesome: string; + images: string; + partials: string; + root: string; + language: string; + purgeCss?: { + content: string[]; + safelist: Array; + }; + playwright?: string | null; +} + +export const defaultRepositoryConfig = { + css: 'input/assets/css/', + js: 'input/assets/js/', + favicons: 'input/', + fontAwesome: 'input/assets/fonts/fontawesome-free/', + images: 'input/assets/images/global-shared/', + partials: 'input/global-partials/', + language: 'cshtml', + purgeCss: { + content: [ + 'input/**/*.cshtml', + 'input/**/*.html', + 'input/**/*.txt', + 'input/**/*.md', + 'input/**/*.hbs', + 'input/**/*.js' + ], + safelist: [ + '::-webkit-scrollbar', + '::-webkit-scrollbar-thumb', + /^fa-(check|triangle-exclamation|info|xmark)/, + /^text-bg-(info|warning|danger|success)/, + /^data-bs-popper/ + + ] + }, + root: './' +}; + +export const repositoryConfig: Record = { + blog: { + ...defaultRepositoryConfig, + name: 'blog', + language: 'hbs' + }, + boxstarter: { + ...defaultRepositoryConfig, + name: 'boxstarter' + }, + community: { + ...defaultRepositoryConfig, + name: 'community', + css: 'Content/css/', + js: 'Scripts/', + favicons: './', + fontAwesome: 'Content/fonts/fontawesome-free/', + images: 'Content/Images/global-shared/', + partials: 'Views/GlobalPartials/' + }, + design: { + ...defaultRepositoryConfig, + name: 'design' + }, + docs: { + ...defaultRepositoryConfig, + name: 'docs' + }, + fest: { + ...defaultRepositoryConfig, + name: 'fest' + }, + org: { + ...defaultRepositoryConfig, + name: 'org', + playwright: 'tests/' + }, + portal: { + ...defaultRepositoryConfig, + name: 'portal', + favicons: 'wwwroot/', + css: 'wwwroot/css/', + js: 'wwwroot/js/', + fontAwesome: 'wwwroot/fonts/fontawesome-free/', + images: 'wwwroot/images/global-shared/', + partials: 'Pages/Global/' + }, + theme: { + name: 'choco-theme', + css: 'node_modules/choco-theme/dist/css/', + js: 'node_modules/choco-theme/dist/js/', + favicons: 'node_modules/choco-theme/images/favicons/', + fontAwesome: 'node_modules/@fortawesome/fontawesome-free/webfonts/', + images: 'node_modules/choco-theme/images/global-shared/', + partials: 'node_modules/choco-theme/dist/partials/', + playwright: 'node_modules/choco-theme/playwright/', + language: 'mixed', + root: 'node_modules/choco-theme/' + }, + zendesk: { + ...defaultRepositoryConfig, + name: 'zendesk', + css: 'assets/', + js: 'assets/', + favicons: 'assets/', + partials: 'global-partials/', + language: 'hbs' + } +}; + +// Merge purgeCss section into the design configuration +repositoryConfig.design.purgeCss = { + ...defaultRepositoryConfig.purgeCss, + safelist: [ + ...defaultRepositoryConfig.purgeCss.safelist, + /^text-bg-(blue|pink|purple|green|red|yellow|orange)(-[0-9]{1,3})?$/ + ] +}; + +// Merge purgeCss section into the community configuration +repositoryConfig.community.purgeCss = { + content: [ + `${repositoryConfig.community.js}*.js`, + `${repositoryConfig.community.partials}*.cshtml`, + 'node_modules/@tarekraafat/autocomplete.js/dist/css/autoComplete.02.css', + 'App_Code/**/*.cshtml', + 'Errors/**/*.*', + 'Views/**/*.*' + ], + safelist: [ + ...defaultRepositoryConfig.purgeCss.safelist, + /^status-/, + 'tt-dataset-0' + ] +}; + +// Merge purgeCss section into the org configuration +repositoryConfig.org.purgeCss = { + content: [ + ...defaultRepositoryConfig.purgeCss.content, + 'node_modules/@splidejs/splide/dist/css/splide-core.min.css', + 'node_modules/nouislider/dist/nouislider.min.css' + ], + safelist: [ + ...defaultRepositoryConfig.purgeCss.safelist, + /^splide-/, + /^splide__/ + ] +}; + +// Merge purgeCss section into the portal configuration +repositoryConfig.portal.purgeCss = { + content: [ + `${repositoryConfig.portal.js}*.js`, + 'Areas/**/*.cshtml', + 'Pages/**/*.cshtml' + ], + safelist: [ + ...defaultRepositoryConfig.purgeCss.safelist, + /^ct-series-/, + /^bg-(secondary|danger|success)/, + /^callout-(danger|success)/, + 'data-license-type', + 'Architect', + 'ManagedServiceProvider', + 'Professional', + 'Business', + 'Trial' + ] +}; + +// Merge purgeCss section into the zendesk configuration +repositoryConfig.zendesk.purgeCss = { + content: [ + `${repositoryConfig.zendesk.js}*.js`, + `${repositoryConfig.zendesk.partials}*.hbs`, + 'templates/**/*.hbs' + ], + safelist: [ + ...defaultRepositoryConfig.purgeCss.safelist, + 'main', + 'table-bordered', + 'table-striped', + 'table-responsive-sm', + 'table-responsive', + 'clear-button', + 'recent-activity-item-meta', + 'chocolatey-zendesk', + 'article-body', + 'pre' + ] +}; diff --git a/build/esbuild.ts b/build/esbuild.ts new file mode 100644 index 00000000..d5a160f3 --- /dev/null +++ b/build/esbuild.ts @@ -0,0 +1,50 @@ +#!/usr/bin/env ts-node + +/*! + * Script to build TS and JS with esbuild. + * Copyright 2020-2024 Chocolatey Software + * Licensed under Apache License (https://github.com/chocolatey/choco-theme/blob/main/LICENSE) + */ + +import * as process from 'process'; +import * as esbuild from 'esbuild'; + +const init = async () => { + const minify = process.argv.includes('--minify'); + + const banner: string = `/*! + * choco-theme v0.6.0 (https://github.com/chocolatey/choco-theme#readme) + * Copyright 2020-2024 Chocolatey Software + * Licensed under MIT (https://github.com/chocolatey/choco-theme/blob/main/LICENSE) +*/`; + + const esbuildOptions: esbuild.BuildOptions = { + entryPoints: ['js/*.js'], + target: 'es2015', + bundle: true, + banner: { + js: banner + }, + outdir: 'dist/js' + }; + + if (minify) { + console.log('🚀 Minifying JS...'); + await esbuild.build({ + ...esbuildOptions, + minify: true, + outExtension: { '.js': '.min.js' } + }).then(() => { + console.log('✅ JS minified'); + }); + } else { + console.log('🚀 Compiling JS and TS...'); + await esbuild.build({ + ...esbuildOptions + }).then(() => { + console.log('✅ JS and TS compiled'); + }); + } +}; + +init(); diff --git a/build/functions/purge-css.ts b/build/functions/purge-css.ts new file mode 100644 index 00000000..f27dade1 --- /dev/null +++ b/build/functions/purge-css.ts @@ -0,0 +1,45 @@ +#!/usr/bin/env ts-node + +/*! + * Function to run PurgeCSS on the CSS files for use in each repository. + * Copyright 2020-2024 Chocolatey Software + * Licensed under Apache License (https://github.com/chocolatey/choco-theme/blob/main/LICENSE) + */ + +import * as fs from 'fs/promises'; +import { PurgeCSS } from 'purgecss'; +import { RepositoryConfig } from '../data/repository-config'; + +export interface PurgeCss { + source: string; + repository: RepositoryConfig; +} + +export const purgeCss = async ({ + source, + repository +}: PurgeCss): Promise => { + console.log('🚀 Purging CSS with PurgeCSS...'); + // Copy non purged CSS and add a temp extension + await fs.cp(source, `${repository.css}${repository.name}.min.temp.css`); + + const purgeCSSResult = await new PurgeCSS().purge({ + content: repository.purgeCss.content, + safelist: repository.purgeCss.safelist, + // fontFace: true, // Note: This is disabled because it was removing Font Awesome fonts + keyframes: true, + // variables: true, // Note: This is stripping out too many CSS variables that are actually in use + css: [source] + }); + + // Write purged content back to the file + await fs.writeFile(source, purgeCSSResult[0].css); + + // Update file name + await fs.rename(source, `${repository.css}${repository.name}.min.purged.css`); + + // Change temp extension of non purged CSS back to original + await fs.rename(`${repository.css}${repository.name}.min.temp.css`, source); + + console.log('✅ PurgeCSS complete'); +}; diff --git a/build/functions/update-content.ts b/build/functions/update-content.ts new file mode 100644 index 00000000..e6ae39e8 --- /dev/null +++ b/build/functions/update-content.ts @@ -0,0 +1,51 @@ +#!/usr/bin/env ts-node + +/*! + * Function to update variable content in a file depending on the repository. + * Copyright 2020-2024 Chocolatey Software + * Licensed under Apache License (https://github.com/chocolatey/choco-theme/blob/main/LICENSE) + */ + +import * as fs from 'fs/promises'; +import path from 'node:path'; + +// General variables +const utf8Encoding = 'utf-8'; + +export interface UpdateContent { + destination: string; + targetFile: string; + targetFileDestination: string; + targetFileContentToReplace: string | null; + replaceWithContent: string; + replacementContentIsFile?: boolean; + replacementTemplate?: string | null; +} + +export const updateContent = async ({ + destination, + targetFile, + targetFileDestination, + targetFileContentToReplace, + replaceWithContent, + replacementContentIsFile = false, + replacementTemplate = null +}: UpdateContent): Promise => { + const originalContent = await fs.readFile(path.join(targetFileDestination, targetFile), utf8Encoding); + + if (replacementContentIsFile) { + replaceWithContent = await fs.readFile(path.join(destination, replaceWithContent), utf8Encoding); + } + + if (replacementTemplate) { + if (!targetFileContentToReplace) { + targetFileContentToReplace = replaceWithContent; + } + + replaceWithContent = replacementTemplate.replaceAll('{0}', replaceWithContent); + } + + const newFile = originalContent.replaceAll(targetFileContentToReplace, replaceWithContent); + + await fs.writeFile(path.join(targetFileDestination, targetFile), newFile, utf8Encoding); +}; diff --git a/build/update-js-content.ts b/build/update-js-content.ts new file mode 100644 index 00000000..ded1230d --- /dev/null +++ b/build/update-js-content.ts @@ -0,0 +1,46 @@ +#!/usr/bin/env ts-node + +/*! + * Script to globally update content of assets. + * Copyright 2020-2024 Chocolatey Software + * Licensed under Apache License (https://github.com/chocolatey/choco-theme/blob/main/LICENSE) + */ + +import { updateContent } from './functions/update-content'; + +const init = async () => { + const fileValidationJs = ['validation.js', 'validation.min.js']; + + for await (const file of fileValidationJs) { + console.log(`🚀 Updating content for ${file}...`); + await updateContent({ + destination: './dist/js', + targetFile: file, + targetFileDestination: './dist/js', + targetFileContentToReplace: 'input-validation-error', + replaceWithContent: 'input-validation-error is-invalid', + replacementContentIsFile: false + }); + + await updateContent({ + destination: './dist/js', + targetFile: file, + targetFileDestination: './dist/js', + targetFileContentToReplace: 'field-validation-error', + replaceWithContent: 'field-validation-error invalid-feedback', + replacementContentIsFile: false + }); + + await updateContent({ + destination: './dist/js', + targetFile: file, + targetFileDestination: './dist/js', + targetFileContentToReplace: '.field-validation-error invalid-feedback', + replaceWithContent: '.field-validation-error.invalid-feedback', + replacementContentIsFile: false + }); + console.log(`✅ Content for ${file} updated`); + } +}; + +init(); diff --git a/getting-started/_bundleconfig.json b/getting-started/_bundleconfig.json deleted file mode 100644 index 16aa3499..00000000 --- a/getting-started/_bundleconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -[ - { - "outputFileName": "input/assets/css/chocolatey.bundle.css", - "inputFiles": [ - "input/assets/css/chocolatey.css" - ] - }, - { - "outputFileName": "input/assets/js/chocolatey-head.bundle.js", - "inputFiles": [ - "input/assets/js/temp/chocolatey-theme-toggle-head.js" - ] - }, - { - "outputFileName": "input/assets/js/chocolatey.bundle.js", - "inputFiles": [ - "input/assets/js/temp/init/chocolatey-${projectName}.js" - ] - } - ] \ No newline at end of file diff --git a/getting-started/_gulpfile.js b/getting-started/_gulpfile.js deleted file mode 100644 index 3b6782f9..00000000 --- a/getting-started/_gulpfile.js +++ /dev/null @@ -1,200 +0,0 @@ -'use strict'; - -const gulp = require('gulp'); -const concat = require('gulp-concat'); -const cleancss = require('gulp-clean-css'); -const uglify = require('gulp-uglify-es').default; -const sass = require('gulp-sass')(require('sass')); -const clean = require('gulp-clean'); -const purgecss = require('gulp-purgecss'); -const rename = require('gulp-rename'); -const merge = require('merge-stream'); -const injectstring = require('gulp-inject-string'); -const browserify = require('browserify'); -const babelify = require('babelify'); -const source = require('vinyl-source-stream'); -const buffer = require('vinyl-buffer'); -const log = require('fancy-log'); -const bundleconfig = require('./bundleconfig.json'); -const fs = require('fs'); -const ts = require('gulp-typescript'); - -const editFilePartial = 'Edit this file at https://github.com/chocolatey/choco-theme/partials'; -const { series, parallel, src, dest } = require('gulp'); - -const regex = { - css: /\.css$/, - js: /\.js$/ -}; - -const paths = { - input: 'input/', - assets: 'input/assets/', - partials: 'input/global-partials', - node_modules: 'node_modules/', - theme: 'node_modules/choco-theme/' -}; - -const tsProject = ts.createProject(`${paths.theme}tsconfig.json`); - -const getBundles = regexPattern => { - return bundleconfig.filter(bundle => { - return regexPattern.test(bundle.outputFileName); - }); -}; - -const del = () => { - return src([ - `${paths.assets}css`, - `${paths.assets}js`, - `${paths.assets}fonts`, - `${paths.assets}images/global-shared`, - paths.partials - ], { allowEmpty: true }) - .pipe(clean({ force: true })); -}; - -const copyTheme = () => { - const copyFontAwesome = src(`${paths.node_modules}@fortawesome/fontawesome-free/webfonts/*.*`) - .pipe(dest(`${paths.assets}fonts/fontawesome-free`)); - - const copyImages = src(`${paths.theme}images/global-shared/*.*`) - .pipe(dest(`${paths.assets}images/global-shared`)); - - const copyIcons = src(`${paths.theme}images/icons/*.*`) - .pipe(dest(paths.input)); - - const copyPartials = src([`${paths.theme}partials/*.*`, `!${paths.theme}partials/AlertText.txt`]) - .pipe(injectstring.prepend(`@* ${editFilePartial} *@\n`)) - .pipe(injectstring.replace(/topNoticeText = ""/, `topNoticeText = "${fs.readFileSync(`${paths.theme}partials/AlertText.txt`, 'utf8')}"`)) - .pipe(injectstring.replace(//, fs.readFileSync(`${paths.theme}partials/ThemeToggle.txt`))) - .pipe(injectstring.replace(//, '')) // eslint-disable-line - .pipe(rename({ prefix: '_', extname: '.cshtml' })) - .pipe(dest(paths.partials)); - - const copyChocoThemeJs = src(`${paths.theme}js/**/*.*`) - .pipe(dest(`${paths.assets}js/temp`)); - - return merge(copyFontAwesome, copyImages, copyIcons, copyPartials, copyChocoThemeJs); -}; - -const compileSass = () => { - return src(`${paths.theme}scss/*.scss`) - .pipe(sass().on('error', sass.logError)) - .pipe(dest(`${paths.assets}css`)); -}; - -const compileTs = () => { - const tsResult = src(`${paths.assets}js/temp/ts/**/*.ts`) - .pipe(tsProject()); - - return tsResult.js.pipe(dest(`${paths.assets}js/temp/ts`)); -}; - -const compileJs = () => { - const tasks = getBundles(regex.js).map(bundle => { - const b = browserify({ - entries: bundle.inputFiles, - debug: true, - transform: [babelify.configure({ - presets: [ - '@babel/preset-env', - ['@babel/preset-react', { runtime: 'automatic' }] - ], - compact: false - })] - }); - - return b.bundle() - .pipe(source(bundle.outputFileName)) - .pipe(buffer()) - .pipe(injectstring.replace('input-validation-error', 'input-validation-error is-invalid')) - .pipe(injectstring.replace('field-validation-error', 'field-validation-error invalid-feedback')) - .on('error', error => { log.error(error.message); }) - .pipe(dest('.')); - }); - - return merge(tasks); -}; - -const compileCss = () => { - const tasks = getBundles(regex.css).map(bundle => { - return gulp.src(bundle.inputFiles, { base: '.' }) - .pipe(concat(bundle.outputFileName)) - .pipe(gulp.dest('.')); - }); - - return merge(tasks); -}; - -const purgeCss = () => { - return src(`${paths.assets}css/chocolatey.bundle.css`) - .pipe(purgecss({ - content: [ - `${paths.input}**/*.cshtml`, - `${paths.input}**/*.md`, - `${paths.assets}js/*.*` - ], - safelist: [ - '::-webkit-scrollbar', - '::-webkit-scrollbar-thumb', - 'link-light', - 'btn-facebook', - 'btn-twitter', - 'btn-linkedin', - 'fa-check', - 'fa-triangle-exclamation', - 'fa-info', - 'fa-xmark' - ], - keyframes: true, - variables: true - })) - .pipe(dest(`${paths.assets}css/`)); -}; - -const minCss = () => { - const tasks = getBundles(regex.css).map(bundle => { - return gulp.src(bundle.outputFileName, { base: '.' }) - .pipe(cleancss({ - level: 2, - compatibility: 'ie8' - })) - .pipe(rename({ suffix: '.min' })) - .pipe(gulp.dest('.')); - }); - - return merge(tasks); -}; - -const minJs = () => { - const tasks = getBundles(regex.js).map(bundle => { - return gulp.src(bundle.outputFileName, { base: '.' }) - .pipe(uglify()) - .pipe(rename({ suffix: '.min' })) - .pipe(dest('.')); - }); - - return merge(tasks); -}; - -const delEnd = () => { - return src([ - `${paths.assets}css/*.css`, - `!${paths.assets}css/*.min.css`, - `${paths.assets}js/*.js`, - `!${paths.assets}js/*.min.js`, - `${paths.assets}js/temp` - ], { allowEmpty: true }) - .pipe(clean({ force: true })); -}; - -// Independent tasks -exports.del = del; - -// Gulp series -exports.compileSassJs = parallel(compileSass, compileJs); -exports.minCssJs = parallel(minCss, minJs); - -// Gulp default -exports.default = series(del, copyTheme, compileTs, exports.compileSassJs, compileCss, purgeCss, exports.minCssJs, delEnd); diff --git a/getting-started/_package.json b/getting-started/_package.json deleted file mode 100644 index 28064bd6..00000000 --- a/getting-started/_package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "chocolatey.org", - "packageManager": "yarn@3.2.0", - "repository": { - "type": "git", - "url": "git+https://github.com/chocolatey/chocolatey.org.git" - }, - "author": "chocolatey", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/chocolatey/chocolatey.org/issues" - }, - "homepage": "https://github.com/chocolatey/chocolatey.org#readme", - "devDependencies": { - "choco-theme": "0.5.28" - }, - "resolutions": { - "glob-parent": "^6.0.2", - "nth-check": "^2.1.1", - "terser": "^5.14.2" - } -} diff --git a/images/icons/apple-touch-icon-114x114.png b/images/favicons/apple-touch-icon-114x114.png similarity index 100% rename from images/icons/apple-touch-icon-114x114.png rename to images/favicons/apple-touch-icon-114x114.png diff --git a/images/icons/apple-touch-icon-120x120.png b/images/favicons/apple-touch-icon-120x120.png similarity index 100% rename from images/icons/apple-touch-icon-120x120.png rename to images/favicons/apple-touch-icon-120x120.png diff --git a/images/icons/apple-touch-icon-144x144.png b/images/favicons/apple-touch-icon-144x144.png similarity index 100% rename from images/icons/apple-touch-icon-144x144.png rename to images/favicons/apple-touch-icon-144x144.png diff --git a/images/icons/apple-touch-icon-152x152.png b/images/favicons/apple-touch-icon-152x152.png similarity index 100% rename from images/icons/apple-touch-icon-152x152.png rename to images/favicons/apple-touch-icon-152x152.png diff --git a/images/icons/apple-touch-icon-180x180.png b/images/favicons/apple-touch-icon-180x180.png similarity index 100% rename from images/icons/apple-touch-icon-180x180.png rename to images/favicons/apple-touch-icon-180x180.png diff --git a/images/icons/apple-touch-icon-57x57.png b/images/favicons/apple-touch-icon-57x57.png similarity index 100% rename from images/icons/apple-touch-icon-57x57.png rename to images/favicons/apple-touch-icon-57x57.png diff --git a/images/icons/apple-touch-icon-72x72.png b/images/favicons/apple-touch-icon-72x72.png similarity index 100% rename from images/icons/apple-touch-icon-72x72.png rename to images/favicons/apple-touch-icon-72x72.png diff --git a/images/icons/apple-touch-icon-76x76.png b/images/favicons/apple-touch-icon-76x76.png similarity index 100% rename from images/icons/apple-touch-icon-76x76.png rename to images/favicons/apple-touch-icon-76x76.png diff --git a/images/icons/apple-touch-icon.png b/images/favicons/apple-touch-icon.png similarity index 100% rename from images/icons/apple-touch-icon.png rename to images/favicons/apple-touch-icon.png diff --git a/images/icons/favicon.ico b/images/favicons/favicon.ico similarity index 100% rename from images/icons/favicon.ico rename to images/favicons/favicon.ico diff --git a/js/blog.js b/js/blog.js new file mode 100644 index 00000000..5ad6d36b --- /dev/null +++ b/js/blog.js @@ -0,0 +1,12 @@ +import './src/lib/prism.min.js'; +import './src/chocolatey-alerts.js'; +import './src/chocolatey-callouts.js'; +import './src/ts/chocolatey-code.ts'; +import './src/chocolatey-collapse-nested.js'; +import './src/chocolatey-markdown.js'; +import './src/chocolatey-anchors.js'; // This is dependent on the markdown script above +import './src/chocolatey-placeholders.js'; +import './src/chocolatey-sticky-table.js'; +import './src/chocolatey-substrings.js'; +import './src/ts/chocolatey-tables.ts'; +import './src/chocolatey-theme-toggle.js'; diff --git a/js/boxstarter.js b/js/boxstarter.js new file mode 100644 index 00000000..5f005b45 --- /dev/null +++ b/js/boxstarter.js @@ -0,0 +1,15 @@ +import './src/lib/prism.min.js'; +import './src/chocolatey-alerts.js'; +import './src/chocolatey-clipboard.js'; +import './src/chocolatey-callouts.js'; +import './src/ts/chocolatey-code.ts'; +import './src/chocolatey-collapse-nested.js'; +import './src/chocolatey-collapse-responsive.js'; +import './src/chocolatey-collapse-y-height.js'; +import './src/chocolatey-docs.js'; +import './src/chocolatey-markdown.js'; +import './src/chocolatey-anchors.js'; // This is dependent on the markdown script above +import './src/chocolatey-scrollspy.js'; +import './src/ts/chocolatey-tab-multiples.ts'; +import './src/ts/chocolatey-tables.ts'; +import './src/chocolatey-theme-toggle.js'; diff --git a/js/community-package-differ.js b/js/community-package-differ.js new file mode 100644 index 00000000..65c7dfa3 --- /dev/null +++ b/js/community-package-differ.js @@ -0,0 +1 @@ +import './src/chocolatey-package-differ.js'; diff --git a/js/community-package-stats.js b/js/community-package-stats.js new file mode 100644 index 00000000..07e80869 --- /dev/null +++ b/js/community-package-stats.js @@ -0,0 +1 @@ +import './src/chocolatey-stats.js'; diff --git a/js/community-packages.js b/js/community-packages.js new file mode 100644 index 00000000..13b6e5a2 --- /dev/null +++ b/js/community-packages.js @@ -0,0 +1,3 @@ +import './community.js'; +import './src/chocolatey-packages.js'; +import './src/chocolatey-script-builder.js'; diff --git a/js/community.js b/js/community.js new file mode 100644 index 00000000..ca18d5b4 --- /dev/null +++ b/js/community.js @@ -0,0 +1,28 @@ +import './src/lib/prism.min.js'; +import './src/chocolatey-alerts.js'; +import './src/chocolatey-announcements.js'; +import './src/chocolatey-authentication.js'; +import './src/chocolatey-carousels.js'; +import './src/chocolatey-clipboard.js'; +import './src/chocolatey-callouts.js'; +import './src/ts/chocolatey-code.ts'; +import './src/chocolatey-collapse-nested.js'; +import './src/chocolatey-collapse-responsive.js'; +import './src/chocolatey-collapse-topnav.js'; +import './src/chocolatey-collapse-y-height.js'; +import './src/chocolatey-dropdown-hover.js'; +import './src/chocolatey-courses.js'; +import './src/chocolatey-internal-url.js'; +import './src/chocolatey-lazyload.js'; +import './src/chocolatey-loader.js'; +import './src/chocolatey-markdown.js'; +import './src/chocolatey-modal-auto-close.js'; +import './src/chocolatey-org.js'; +import './src/chocolatey-scrollspy.js'; +import './src/chocolatey-search.js'; +import './src/chocolatey-show-hide.js'; +import './src/chocolatey-shuffle.js'; +import './src/ts/chocolatey-tab-multiples.ts'; +import './src/chocolatey-terminal.js'; +import './src/chocolatey-tooltips.js'; +import './src/chocolatey-theme-toggle.js'; diff --git a/js/design.js b/js/design.js new file mode 100644 index 00000000..3fad2dd3 --- /dev/null +++ b/js/design.js @@ -0,0 +1,16 @@ +import './src/lib/prism.min.js'; +import './src/chocolatey-alerts.js'; +import './src/chocolatey-code-copy-for-view.js'; // Purposely put before callouts.js because this script needs to execute first +import './src/chocolatey-callouts.js'; +import './src/ts/chocolatey-code.ts'; +import './src/chocolatey-collapse-nested.js'; +import './src/chocolatey-collapse-responsive.js'; +import './src/chocolatey-collapse-y-height.js'; +import './src/chocolatey-docs.js'; +import './src/chocolatey-lazyload.js'; +import './src/chocolatey-markdown.js'; +import './src/chocolatey-anchors.js'; // This is dependent on the markdown script above +import './src/chocolatey-scrollspy.js'; +import './src/ts/chocolatey-tab-multiples.ts'; +import './src/ts/chocolatey-tables.ts'; +import './src/chocolatey-theme-toggle.js'; diff --git a/js/docs.js b/js/docs.js new file mode 100644 index 00000000..20192772 --- /dev/null +++ b/js/docs.js @@ -0,0 +1,15 @@ +import './src/lib/prism.min.js'; +import './src/chocolatey-alerts.js'; +import './src/chocolatey-callouts.js'; +import './src/ts/chocolatey-code.ts'; +import './src/chocolatey-collapse-nested.js'; +import './src/chocolatey-collapse-responsive.js'; +import './src/chocolatey-collapse-y-height.js'; +import './src/chocolatey-docs.js'; +import './src/chocolatey-docsearch.js'; +import './src/chocolatey-markdown.js'; +import './src/chocolatey-anchors.js'; // This is dependent on the markdown script above +import './src/chocolatey-scrollspy.js'; +import './src/ts/chocolatey-tab-multiples.ts'; +import './src/ts/chocolatey-tables.ts'; +import './src/chocolatey-theme-toggle.js'; diff --git a/js/fest.js b/js/fest.js new file mode 100644 index 00000000..f45452c8 --- /dev/null +++ b/js/fest.js @@ -0,0 +1,7 @@ +import 'lite-youtube-embed'; +import './src/chocolatey-alerts.js'; +import './src/chocolatey-callouts.js'; +import './src/chocolatey-lazyload.js'; +import './src/chocolatey-org.js'; +import './src/chocolatey-sticky-top.js'; +import './src/chocolatey-theme-toggle.js'; diff --git a/js/init/chocolatey-blog.js b/js/init/chocolatey-blog.js deleted file mode 100644 index 21731282..00000000 --- a/js/init/chocolatey-blog.js +++ /dev/null @@ -1,13 +0,0 @@ -import { Alert, Button, Carousel, Collapse } from 'bootstrap'; -import '../lib/prism.min.js'; -import '../chocolatey-alerts.js'; -import '../chocolatey-callouts.js'; -import '../ts/chocolatey-code.js'; -import '../chocolatey-collapse-nested.js'; -import '../chocolatey-markdown.js'; -import '../chocolatey-anchors.js'; // This is dependent on the markdown script above -import '../chocolatey-placeholders.js'; -import '../chocolatey-sticky-table.js'; -import '../chocolatey-substrings.js'; -import '../ts/chocolatey-tables.js'; -import '../chocolatey-theme-toggle.js'; diff --git a/js/init/chocolatey-boxstarter-org.js b/js/init/chocolatey-boxstarter-org.js deleted file mode 100644 index 187bfb65..00000000 --- a/js/init/chocolatey-boxstarter-org.js +++ /dev/null @@ -1,16 +0,0 @@ -import { Alert, Button, Collapse } from 'bootstrap'; -import '../lib/prism.min.js'; -import '../chocolatey-alerts.js'; -import '../chocolatey-clipboard.js'; -import '../chocolatey-callouts.js'; -import '../ts/chocolatey-code.js'; -import '../chocolatey-collapse-nested.js'; -import '../chocolatey-collapse-responsive.js'; -import '../chocolatey-collapse-y-height.js'; -import '../chocolatey-docs.js'; -import '../chocolatey-markdown.js'; -import '../chocolatey-anchors.js'; // This is dependent on the markdown script above -import '../chocolatey-scrollspy.js'; -import '../ts/chocolatey-tab-multiples.js'; -import '../ts/chocolatey-tables.js'; -import '../chocolatey-theme-toggle.js'; diff --git a/js/init/chocolatey-community.js b/js/init/chocolatey-community.js deleted file mode 100644 index 06326813..00000000 --- a/js/init/chocolatey-community.js +++ /dev/null @@ -1,31 +0,0 @@ -import { Alert, Button, Carousel, Collapse, Dropdown, Modal, Offcanvas, Tab } from 'bootstrap'; -import { atcb_init } from 'add-to-calendar-button'; // eslint-disable-line camelcase -import '../lib/prism.min.js'; -import '../chocolatey-alerts.js'; -import '../chocolatey-announcements.js'; -import '../chocolatey-authentication.js'; -import '../chocolatey-carousels.js'; -import '../chocolatey-clipboard.js'; -import '../chocolatey-callouts.js'; -import '../ts/chocolatey-code.js'; -import '../chocolatey-collapse-nested.js'; -import '../chocolatey-collapse-responsive.js'; -import '../chocolatey-collapse-topnav.js'; -import '../chocolatey-collapse-y-height.js'; -import '../chocolatey-dropdown-hover.js'; -import '../chocolatey-courses.js'; -import '../chocolatey-internal-url.js'; -import '../chocolatey-lazyload.js'; -import '../chocolatey-loader.js'; -import '../chocolatey-markdown.js'; -import '../chocolatey-modal-auto-close.js'; -import '../chocolatey-org.js'; -import '../chocolatey-scrollspy.js'; -import '../chocolatey-search.js'; -import '../chocolatey-show-hide.js'; -import '../chocolatey-shuffle.js'; -import '../ts/chocolatey-tab-multiples.js'; -import '../chocolatey-terminal.js'; -import '../chocolatey-tooltips.js'; -import '../chocolatey-theme-toggle.js'; -atcb_init(); diff --git a/js/init/chocolatey-design.js b/js/init/chocolatey-design.js deleted file mode 100644 index 2ad77d8a..00000000 --- a/js/init/chocolatey-design.js +++ /dev/null @@ -1,17 +0,0 @@ -import { Alert, Button, Collapse, Modal, Tab } from 'bootstrap'; -import '../lib/prism.min.js'; -import '../chocolatey-alerts.js'; -import '../chocolatey-code-copy-for-view.js'; // Purposely put before callouts.js because this script needs to execute first -import '../chocolatey-callouts.js'; -import '../ts/chocolatey-code.js'; -import '../chocolatey-collapse-nested.js'; -import '../chocolatey-collapse-responsive.js'; -import '../chocolatey-collapse-y-height.js'; -import '../chocolatey-docs.js'; -import '../chocolatey-lazyload.js'; -import '../chocolatey-markdown.js'; -import '../chocolatey-anchors.js'; // This is dependent on the markdown script above -import '../chocolatey-scrollspy.js'; -import '../ts/chocolatey-tab-multiples.js'; -import '../ts/chocolatey-tables.js'; -import '../chocolatey-theme-toggle.js'; diff --git a/js/init/chocolatey-docs.js b/js/init/chocolatey-docs.js deleted file mode 100644 index bc939165..00000000 --- a/js/init/chocolatey-docs.js +++ /dev/null @@ -1,15 +0,0 @@ -import { Alert, Button, Collapse, Tab } from 'bootstrap'; -import '../lib/prism.min.js'; -import '../chocolatey-alerts.js'; -import '../chocolatey-callouts.js'; -import '../ts/chocolatey-code.js'; -import '../chocolatey-collapse-nested.js'; -import '../chocolatey-collapse-responsive.js'; -import '../chocolatey-collapse-y-height.js'; -import '../chocolatey-docs.js'; -import '../chocolatey-markdown.js'; -import '../chocolatey-anchors.js'; // This is dependent on the markdown script above -import '../chocolatey-scrollspy.js'; -import '../ts/chocolatey-tab-multiples.js'; -import '../ts/chocolatey-tables.js'; -import '../chocolatey-theme-toggle.js'; diff --git a/js/init/chocolatey-fest.js b/js/init/chocolatey-fest.js deleted file mode 100644 index edc82e68..00000000 --- a/js/init/chocolatey-fest.js +++ /dev/null @@ -1,8 +0,0 @@ -import { Alert, Button, Collapse, Modal, Tab } from 'bootstrap'; -import 'lite-youtube-embed'; -import '../chocolatey-alerts.js'; -import '../chocolatey-callouts.js'; -import '../chocolatey-lazyload.js'; -import '../chocolatey-org.js'; -import '../chocolatey-sticky-top.js'; -import '../chocolatey-theme-toggle.js'; diff --git a/js/init/chocolatey-org.js b/js/init/chocolatey-org.js deleted file mode 100644 index 01f893db..00000000 --- a/js/init/chocolatey-org.js +++ /dev/null @@ -1,32 +0,0 @@ -import { Alert, Button, Carousel, Collapse, Modal, Offcanvas, Tab } from 'bootstrap'; -import { atcb_init } from 'add-to-calendar-button'; // eslint-disable-line camelcase -import balanceText from 'balance-text'; -import '../lib/prism.min.js'; -import '../chocolatey-alerts.js'; -import '../chocolatey-announcements.js'; -import '../chocolatey-carousels.js'; -import '../chocolatey-clipboard.js'; -import '../chocolatey-callouts.js'; -import '../ts/chocolatey-code.js'; -import '../chocolatey-collapse-nested.js'; -import '../chocolatey-collapse-responsive.js'; -import '../chocolatey-collapse-topnav.js'; -import '../chocolatey-collapse-y-height.js'; -import '../chocolatey-dropdown-hover.js'; -import '../chocolatey-internal-url.js'; -import '../chocolatey-lazyload.js'; -import '../chocolatey-loader.js'; -import '../chocolatey-markdown.js'; -import '../chocolatey-org.js'; -import '../chocolatey-pricing-calculator.js'; -import '../chocolatey-scrollspy.js'; -import '../chocolatey-show-hide.js'; -import '../chocolatey-shuffle.js'; -import '../chocolatey-splide.js'; -import '../chocolatey-sticky-top.js'; -import '../ts/chocolatey-tab-multiples.js'; -import '../chocolatey-terminal.js'; -import '../chocolatey-theme-toggle.js'; -import '../chocolatey-toggle-fade-show.js'; -atcb_init(); -balanceText(); diff --git a/js/init/chocolatey-portal.js b/js/init/chocolatey-portal.js deleted file mode 100644 index 5933dfc6..00000000 --- a/js/init/chocolatey-portal.js +++ /dev/null @@ -1,13 +0,0 @@ -import { Alert, Button, Collapse, Dropdown, Modal, Tab } from 'bootstrap'; -import '../lib/prism.min.js'; -import '../chocolatey-callouts.js'; -import '../ts/chocolatey-code.js'; -import '../chocolatey-collapse-nested.js'; -import '../chocolatey-collapse-responsive.js'; -import '../chocolatey-collapse-y-height.js'; -import '../chocolatey-markdown.js'; -import '../chocolatey-scrollspy.js'; -import '../chocolatey-theme-toggle.js'; -import '../../src/util/reset-modal.js'; -import '../../src/util/reset-toast.js'; -import '../../src/util/status-modal.js'; diff --git a/js/init/chocolatey-zendesk.js b/js/init/chocolatey-zendesk.js deleted file mode 100644 index b37b3d83..00000000 --- a/js/init/chocolatey-zendesk.js +++ /dev/null @@ -1,3 +0,0 @@ -import '../chocolatey-inputs.js'; -import '../ts/chocolatey-tables.js'; -import '../chocolatey-theme-toggle.js'; diff --git a/js/org.js b/js/org.js new file mode 100644 index 00000000..2a968f65 --- /dev/null +++ b/js/org.js @@ -0,0 +1,31 @@ +import { atcb_init } from 'add-to-calendar-button'; // eslint-disable-line camelcase +import balanceText from 'balance-text'; +import './src/lib/prism.min.js'; +import './src/chocolatey-alerts.js'; +import './src/chocolatey-announcements.js'; +import './src/chocolatey-carousels.js'; +import './src/chocolatey-clipboard.js'; +import './src/chocolatey-callouts.js'; +import './src/ts/chocolatey-code.ts'; +import './src/chocolatey-collapse-nested.js'; +import './src/chocolatey-collapse-responsive.js'; +import './src/chocolatey-collapse-topnav.js'; +import './src/chocolatey-collapse-y-height.js'; +import './src/chocolatey-dropdown-hover.js'; +import './src/chocolatey-internal-url.js'; +import './src/chocolatey-lazyload.js'; +import './src/chocolatey-loader.js'; +import './src/chocolatey-markdown.js'; +import './src/chocolatey-org.js'; +import './src/chocolatey-pricing-calculator.js'; +import './src/chocolatey-scrollspy.js'; +import './src/chocolatey-show-hide.js'; +import './src/chocolatey-shuffle.js'; +import './src/chocolatey-splide.js'; +import './src/chocolatey-sticky-top.js'; +import './src/ts/chocolatey-tab-multiples.ts'; +import './src/chocolatey-terminal.js'; +import './src/chocolatey-theme-toggle.js'; +import './src/chocolatey-toggle-fade-show.js'; +atcb_init(); +balanceText(); diff --git a/js/portal.js b/js/portal.js new file mode 100644 index 00000000..da1c36be --- /dev/null +++ b/js/portal.js @@ -0,0 +1,12 @@ +import './src/lib/prism.min.js'; +import './src/chocolatey-callouts.js'; +import './src/ts/chocolatey-code.ts'; +import './src/chocolatey-collapse-nested.js'; +import './src/chocolatey-collapse-responsive.js'; +import './src/chocolatey-collapse-y-height.js'; +import './src/chocolatey-markdown.js'; +import './src/chocolatey-scrollspy.js'; +import './src/chocolatey-theme-toggle.js'; +import './src/reset-modal.js'; +import './src/reset-toast.js'; +import './src/status-modal.js'; diff --git a/js/chocolatey-alerts.js b/js/src/chocolatey-alerts.js similarity index 100% rename from js/chocolatey-alerts.js rename to js/src/chocolatey-alerts.js diff --git a/js/chocolatey-anchors.js b/js/src/chocolatey-anchors.js similarity index 100% rename from js/chocolatey-anchors.js rename to js/src/chocolatey-anchors.js diff --git a/js/chocolatey-announcements.js b/js/src/chocolatey-announcements.js similarity index 100% rename from js/chocolatey-announcements.js rename to js/src/chocolatey-announcements.js diff --git a/js/chocolatey-authentication.js b/js/src/chocolatey-authentication.js similarity index 100% rename from js/chocolatey-authentication.js rename to js/src/chocolatey-authentication.js diff --git a/js/chocolatey-birthday.js b/js/src/chocolatey-birthday.js similarity index 91% rename from js/chocolatey-birthday.js rename to js/src/chocolatey-birthday.js index d096bc84..60e1d5aa 100644 --- a/js/chocolatey-birthday.js +++ b/js/src/chocolatey-birthday.js @@ -21,7 +21,9 @@ import { getCookie, setCookieExpirationNever } from './util/chocolatey-functions const particleCount = 50 * (timeLeft / duration); // since particles fall down, start a bit higher than random + // eslint-disable-next-line object-shorthand confetti(Object.assign({}, defaults, { particleCount, origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 } })); + // eslint-disable-next-line object-shorthand confetti(Object.assign({}, defaults, { particleCount, origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 } })); }, 250); }; diff --git a/js/chocolatey-callouts.js b/js/src/chocolatey-callouts.js similarity index 100% rename from js/chocolatey-callouts.js rename to js/src/chocolatey-callouts.js diff --git a/js/chocolatey-carousels.js b/js/src/chocolatey-carousels.js similarity index 100% rename from js/chocolatey-carousels.js rename to js/src/chocolatey-carousels.js diff --git a/js/chocolatey-clipboard.js b/js/src/chocolatey-clipboard.js similarity index 100% rename from js/chocolatey-clipboard.js rename to js/src/chocolatey-clipboard.js diff --git a/js/chocolatey-code-copy-for-view.js b/js/src/chocolatey-code-copy-for-view.js similarity index 100% rename from js/chocolatey-code-copy-for-view.js rename to js/src/chocolatey-code-copy-for-view.js diff --git a/js/chocolatey-collapse-nested.js b/js/src/chocolatey-collapse-nested.js similarity index 100% rename from js/chocolatey-collapse-nested.js rename to js/src/chocolatey-collapse-nested.js diff --git a/js/chocolatey-collapse-responsive.js b/js/src/chocolatey-collapse-responsive.js similarity index 100% rename from js/chocolatey-collapse-responsive.js rename to js/src/chocolatey-collapse-responsive.js diff --git a/js/chocolatey-collapse-topnav.js b/js/src/chocolatey-collapse-topnav.js similarity index 100% rename from js/chocolatey-collapse-topnav.js rename to js/src/chocolatey-collapse-topnav.js diff --git a/js/chocolatey-collapse-y-height.js b/js/src/chocolatey-collapse-y-height.js similarity index 100% rename from js/chocolatey-collapse-y-height.js rename to js/src/chocolatey-collapse-y-height.js diff --git a/js/chocolatey-courses.js b/js/src/chocolatey-courses.js similarity index 100% rename from js/chocolatey-courses.js rename to js/src/chocolatey-courses.js diff --git a/js/chocolatey-docs.js b/js/src/chocolatey-docs.js similarity index 100% rename from js/chocolatey-docs.js rename to js/src/chocolatey-docs.js diff --git a/js/chocolatey-docsearch.js b/js/src/chocolatey-docsearch.js similarity index 100% rename from js/chocolatey-docsearch.js rename to js/src/chocolatey-docsearch.js diff --git a/js/chocolatey-dropdown-hover.js b/js/src/chocolatey-dropdown-hover.js similarity index 100% rename from js/chocolatey-dropdown-hover.js rename to js/src/chocolatey-dropdown-hover.js diff --git a/js/chocolatey-events.js b/js/src/chocolatey-events.js similarity index 100% rename from js/chocolatey-events.js rename to js/src/chocolatey-events.js diff --git a/js/chocolatey-inputs.js b/js/src/chocolatey-inputs.js similarity index 100% rename from js/chocolatey-inputs.js rename to js/src/chocolatey-inputs.js diff --git a/js/chocolatey-internal-url.js b/js/src/chocolatey-internal-url.js similarity index 100% rename from js/chocolatey-internal-url.js rename to js/src/chocolatey-internal-url.js diff --git a/js/chocolatey-lazyload.js b/js/src/chocolatey-lazyload.js similarity index 100% rename from js/chocolatey-lazyload.js rename to js/src/chocolatey-lazyload.js diff --git a/js/chocolatey-loader.js b/js/src/chocolatey-loader.js similarity index 100% rename from js/chocolatey-loader.js rename to js/src/chocolatey-loader.js diff --git a/js/chocolatey-markdown.js b/js/src/chocolatey-markdown.js similarity index 100% rename from js/chocolatey-markdown.js rename to js/src/chocolatey-markdown.js diff --git a/js/chocolatey-modal-auto-close.js b/js/src/chocolatey-modal-auto-close.js similarity index 100% rename from js/chocolatey-modal-auto-close.js rename to js/src/chocolatey-modal-auto-close.js diff --git a/js/chocolatey-multi-tab.js b/js/src/chocolatey-multi-tab.js similarity index 100% rename from js/chocolatey-multi-tab.js rename to js/src/chocolatey-multi-tab.js diff --git a/js/chocolatey-org.js b/js/src/chocolatey-org.js similarity index 100% rename from js/chocolatey-org.js rename to js/src/chocolatey-org.js diff --git a/js/chocolatey-package-differ.js b/js/src/chocolatey-package-differ.js similarity index 100% rename from js/chocolatey-package-differ.js rename to js/src/chocolatey-package-differ.js diff --git a/js/chocolatey-packages.js b/js/src/chocolatey-packages.js similarity index 100% rename from js/chocolatey-packages.js rename to js/src/chocolatey-packages.js diff --git a/js/chocolatey-placeholders.js b/js/src/chocolatey-placeholders.js similarity index 100% rename from js/chocolatey-placeholders.js rename to js/src/chocolatey-placeholders.js diff --git a/js/chocolatey-pricing-calculator.js b/js/src/chocolatey-pricing-calculator.js similarity index 97% rename from js/chocolatey-pricing-calculator.js rename to js/src/chocolatey-pricing-calculator.js index 926391f6..78e7b319 100644 --- a/js/chocolatey-pricing-calculator.js +++ b/js/src/chocolatey-pricing-calculator.js @@ -29,6 +29,7 @@ window.addEventListener('DOMContentLoaded', () => { '50%': [2000], max: [c4bNodeDefaults.maxNodes] }, + // eslint-disable-next-line object-shorthand format: { to: function (value) { // Must return a string diff --git a/js/chocolatey-script-builder.js b/js/src/chocolatey-script-builder.js similarity index 100% rename from js/chocolatey-script-builder.js rename to js/src/chocolatey-script-builder.js diff --git a/js/chocolatey-scrollspy.js b/js/src/chocolatey-scrollspy.js similarity index 100% rename from js/chocolatey-scrollspy.js rename to js/src/chocolatey-scrollspy.js diff --git a/js/chocolatey-search.js b/js/src/chocolatey-search.js similarity index 100% rename from js/chocolatey-search.js rename to js/src/chocolatey-search.js diff --git a/js/chocolatey-show-hide.js b/js/src/chocolatey-show-hide.js similarity index 100% rename from js/chocolatey-show-hide.js rename to js/src/chocolatey-show-hide.js diff --git a/js/chocolatey-shuffle.js b/js/src/chocolatey-shuffle.js similarity index 100% rename from js/chocolatey-shuffle.js rename to js/src/chocolatey-shuffle.js diff --git a/js/chocolatey-splide.js b/js/src/chocolatey-splide.js similarity index 100% rename from js/chocolatey-splide.js rename to js/src/chocolatey-splide.js diff --git a/js/chocolatey-stats.js b/js/src/chocolatey-stats.js similarity index 100% rename from js/chocolatey-stats.js rename to js/src/chocolatey-stats.js diff --git a/js/chocolatey-sticky-table.js b/js/src/chocolatey-sticky-table.js similarity index 100% rename from js/chocolatey-sticky-table.js rename to js/src/chocolatey-sticky-table.js diff --git a/js/chocolatey-sticky-top.js b/js/src/chocolatey-sticky-top.js similarity index 100% rename from js/chocolatey-sticky-top.js rename to js/src/chocolatey-sticky-top.js diff --git a/js/chocolatey-substrings.js b/js/src/chocolatey-substrings.js similarity index 100% rename from js/chocolatey-substrings.js rename to js/src/chocolatey-substrings.js diff --git a/js/chocolatey-terminal.js b/js/src/chocolatey-terminal.js similarity index 100% rename from js/chocolatey-terminal.js rename to js/src/chocolatey-terminal.js diff --git a/js/chocolatey-theme-toggle.js b/js/src/chocolatey-theme-toggle.js similarity index 100% rename from js/chocolatey-theme-toggle.js rename to js/src/chocolatey-theme-toggle.js diff --git a/js/chocolatey-toggle-fade-show.js b/js/src/chocolatey-toggle-fade-show.js similarity index 100% rename from js/chocolatey-toggle-fade-show.js rename to js/src/chocolatey-toggle-fade-show.js diff --git a/js/chocolatey-tooltips.js b/js/src/chocolatey-tooltips.js similarity index 100% rename from js/chocolatey-tooltips.js rename to js/src/chocolatey-tooltips.js diff --git a/js/lib/jquery-datatables.js b/js/src/lib/jquery-datatables.js similarity index 100% rename from js/lib/jquery-datatables.js rename to js/src/lib/jquery-datatables.js diff --git a/js/lib/prism.min.js b/js/src/lib/prism.min.js similarity index 100% rename from js/lib/prism.min.js rename to js/src/lib/prism.min.js diff --git a/js/src/reset-modal.js b/js/src/reset-modal.js new file mode 100644 index 00000000..352f1aae --- /dev/null +++ b/js/src/reset-modal.js @@ -0,0 +1,34 @@ +(() => { + // On modal close, set back to defaults + const allModals = document.querySelectorAll('.modal'); + + allModals.forEach(el => { + el.addEventListener('hidden.bs.modal', () => { + const modalId = el.querySelector('.modal-id'); + + if (modalId) { + modalId.value = ''; + } + + // Deactivate modal + if (el.id == 'modalDeactivateLicense') { + const reasonTrial = document.querySelector('.deactivate-reason-trial'); + const reasonFull = document.querySelector('.deactivate-reason-license'); + const deactivateReasonBtn = document.querySelectorAll('.deactivate-reason.btn-check'); + const deactivateReasonCustom = document.querySelector('.deactivate-reason.form-control'); + const btnDeactivateLicenseConfirm = document.querySelector('.btn-deactivate-license-confirm'); + + reasonTrial.classList.add('d-none'); + reasonFull.classList.add('d-none'); + + deactivateReasonBtn.forEach(el => { + el.checked = false; + el.disabled = false; + }); + + deactivateReasonCustom.value = ''; + btnDeactivateLicenseConfirm.disabled = true; + } + }); + }); +})(); diff --git a/js/src/reset-toast.js b/js/src/reset-toast.js new file mode 100644 index 00000000..ffe597db --- /dev/null +++ b/js/src/reset-toast.js @@ -0,0 +1,9 @@ +(() => { + const toast = document.querySelector('.toast'); + + if (toast) { + toast.addEventListener('hidden.bs.toast', () => { + toast.classList.remove('text-bg-success', 'text-bg-danger', 'text-bg-secondary'); + }); + } +})(); diff --git a/js/src/status-modal.js b/js/src/status-modal.js new file mode 100644 index 00000000..b6118c1f --- /dev/null +++ b/js/src/status-modal.js @@ -0,0 +1,16 @@ +import { Modal } from 'bootstrap'; + +(() => { + // Trigger status message modal if present, destroy on hide + const statusMessage = document.getElementById('modalStatusMessage'); + + if (statusMessage) { + const statusMessageModal = Modal.getOrCreateInstance(statusMessage, { keyboard: false, backdrop: 'static' }); + + statusMessageModal.show(); + + statusMessage.addEventListener('hidden.bs.modal', () => { + statusMessageModal.dispose(); + }); + } +})(); diff --git a/js/ts/chocolatey-code.ts b/js/src/ts/chocolatey-code.ts similarity index 100% rename from js/ts/chocolatey-code.ts rename to js/src/ts/chocolatey-code.ts diff --git a/js/ts/chocolatey-tab-multiples.ts b/js/src/ts/chocolatey-tab-multiples.ts similarity index 100% rename from js/ts/chocolatey-tab-multiples.ts rename to js/src/ts/chocolatey-tab-multiples.ts diff --git a/js/ts/chocolatey-tables.ts b/js/src/ts/chocolatey-tables.ts similarity index 100% rename from js/ts/chocolatey-tables.ts rename to js/src/ts/chocolatey-tables.ts diff --git a/js/ts/util/chocolatey-functions.ts b/js/src/ts/util/chocolatey-functions.ts similarity index 100% rename from js/ts/util/chocolatey-functions.ts rename to js/src/ts/util/chocolatey-functions.ts diff --git a/js/ts/util/chocolatey-pricing-calculator.ts b/js/src/ts/util/chocolatey-pricing-calculator.ts similarity index 100% rename from js/ts/util/chocolatey-pricing-calculator.ts rename to js/src/ts/util/chocolatey-pricing-calculator.ts diff --git a/js/util/chocolatey-functions.js b/js/src/util/chocolatey-functions.js similarity index 100% rename from js/util/chocolatey-functions.js rename to js/src/util/chocolatey-functions.js diff --git a/js/chocolatey-theme-toggle-head.js b/js/theme-toggle.js similarity index 100% rename from js/chocolatey-theme-toggle-head.js rename to js/theme-toggle.js diff --git a/js/init/chocolatey-jquery-validation.js b/js/validation.js similarity index 100% rename from js/init/chocolatey-jquery-validation.js rename to js/validation.js diff --git a/js/zendesk.js b/js/zendesk.js new file mode 100644 index 00000000..d1068560 --- /dev/null +++ b/js/zendesk.js @@ -0,0 +1,3 @@ +import './src/chocolatey-inputs.js'; +import './src/ts/chocolatey-tables.ts'; +import './src/chocolatey-theme-toggle.js'; diff --git a/package.json b/package.json index 29487c57..8569c718 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "choco-theme", - "version": "0.5.28", + "version": "0.6.0", "description": "The global theme for Chocolatey Software.", "repository": { "type": "git", @@ -12,80 +12,85 @@ "url": "https://github.com/chocolatey/choco-theme/issues" }, "homepage": "https://github.com/chocolatey/choco-theme#readme", - "browser": "js/init/chocolatey-org.js", - "main": "js/init/chocolatey-org.js", - "sass": "scss/chocolatey.scss", + "scripts": { + "build": "npm run --silent clean && npm-run-all --parallel --silent css js partials && echo 🎉 Build complete", + "change-version": "ts-node build/change-version.ts", + "css": "npm-run-all --sequential --silent css-compile css-minify", + "css-compile": "echo 🚀 Compiling SASS... && sass --load-path=node_modules --style=expanded --no-source-map --stop-on-error --quiet scss/:dist/css/ && echo ✅ SASS compiled", + "css-minify": "echo 🚀 Minifying CSS... && npm-run-all --parallel --silent css-minify-* && echo ✅ CSS minified", + "css-minify-chocolatey": "postcss dist/css/chocolatey.css > dist/css/chocolatey.min.css", + "css-minify-boxstarter": "postcss dist/css/boxstarter.css > dist/css/boxstarter.min.css", + "css-minify-zendesk": "postcss dist/css/zendesk.css > dist/css/zendesk.min.css", + "clean": "rimraf dist/", + "js": "npm-run-all --parallel --silent js-bundle js-minify && npm run --silent js-content", + "js-bundle": "ts-node build/esbuild.ts", + "js-content": "ts-node build/update-js-content.ts", + "js-minify": "ts-node build/esbuild.ts --minify", + "lint": "npm-run-all --parallel --silent lint-*", + "lint-css": "echo 🚀 Linting SASS... && stylelint \"scss/**/*.scss\" --cache --cache-location .cache/.stylelintcache && echo ✅ SASS linting complete", + "lint-js": "echo 🚀 Linting JS and TS... && eslint js/**/*.{js,ts} && echo ✅ JS and TS linting complete", + "partials": "ts-node build/build-partials.ts", + "watch": "npm-run-all --parallel watch-*", + "watch-css": "nodemon --watch scss/ --ext scss --exec \"npm run css\"", + "watch-js": "nodemon --watch js/ --ext js --exec \"npm run js\"", + "watch-partials": "nodemon --watch partials/ --ext html --exec \"npm run partials\"" + }, "dependencies": { - "@babel/core": "^7.18.9", - "@babel/preset-env": "^7.18.9", - "@babel/preset-react": "^7.18.6", "@docsearch/css": "^3.3.3", "@docsearch/js": "^3.3.3", "@fortawesome/fontawesome-free": "^6.1.2", "@playwright/test": "1.35.1", - "@popperjs/core": "^2.11.5", + "@popperjs/core": "^2.11.8", "@splidejs/splide": "^4.1.4", "@splidejs/splide-extension-auto-scroll": "^0.5.3", "@splidejs/splide-extension-intersection": "^0.2.0", "@tarekraafat/autocomplete.js": "^10.2.7", - "@types/bootstrap": "5.2.6", + "@types/bootstrap": "^5.2.10", "@types/luxon": "^3.3.0", + "@types/node": "^20.11.25", "@types/prismjs": "^1.26.0", - "@typescript-eslint/eslint-plugin": "^5.58.0", - "@typescript-eslint/parser": "^5.58.0", + "@typescript-eslint/eslint-plugin": "^7.2.0", + "@typescript-eslint/parser": "^7.2.0", "add-to-calendar-button": "^1.18.8", - "anchor-js": "^4.3.1", - "babelify": "^10.0.0", + "anchor-js": "^5.0.0", "balance-text": "^3.3.1", - "bootstrap": "5.2.3", - "browserify": "^17.0.0", + "bootstrap": "5.3.3", "canvas-confetti": "^1.5.1", "chartist": "^0.11.4", "chartist-plugin-legend": "^0.6.2", "clipboard": "^2.0.11", + "cssnano": "^6.1.0", "datatables.net": "1.13.1", "easymde": "^2.16.1", - "eslint": "^8.0.1", + "esbuild": "^0.20.1", + "eslint": "^8.57.0", "eslint-config-standard": "^17.0.0", - "eslint-plugin-import": "^2.25.2", - "eslint-plugin-n": "^15.0.0", - "eslint-plugin-playwright": "^0.15.3", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-n": "^16.6.2", + "eslint-plugin-playwright": "^1.4.1", "eslint-plugin-promise": "^6.0.0", - "fancy-log": "^2.0.0", "flatpickr": "^4.6.13", - "gulp": "^4.0.2", - "gulp-clean": "^0.4.0", - "gulp-clean-css": "^4.3.0", - "gulp-concat": "^2.6.1", - "gulp-inject-string": "^1.1.2", - "gulp-inline-source": "^4.0.0", - "gulp-purgecss": "^4.1.3", - "gulp-rename": "^2.0.0", - "gulp-sass": "^5.1.0", - "gulp-typescript": "^6.0.0-alpha.1", - "gulp-uglify-es": "^3.0.0", - "jquery": "^3.6.0", + "jquery": "^3.7.1", "jquery-validation": "^1.19.5", "jquery-validation-unobtrusive": "^4.0.0", - "lite-youtube-embed": "^0.2.0", + "lite-youtube-embed": "^0.3.0", "luxon": "^3.0.1", - "marked": "^4.0.18", - "merge-stream": "^2.0.0", + "marked": "^12.0.0", "mousetrap": "^1.6.5", + "nodemon": "^3.1.0", "nouislider": "^15.7.0", - "rimraf": "^3.0.2", - "sass": "~1.64.2", - "stylelint": "^14.14.0", - "stylelint-config-standard": "^29.0.0", - "stylelint-config-standard-scss": "^5.0.0", - "stylelint-config-twbs-bootstrap": "^6.0.0", - "typescript": "5.0.4", - "vinyl-buffer": "^1.0.1", - "vinyl-source-stream": "^2.0.0" - }, - "resolutions": { - "glob-parent": "^6.0.2", - "nth-check": "^2.1.1", - "terser": "^5.14.2" + "npm-run-all2": "^6.1.2", + "postcss": "^8.4.35", + "postcss-cli": "^11.0.0", + "postcss-preset-env": "^9.5.0", + "purgecss": "^5.0.0", + "rimraf": "^5.0.5", + "sass": "^1.71.1", + "stylelint": "^16.3.1", + "stylelint-config-standard": "^36.0.0", + "stylelint-config-standard-scss": "^13.0.0", + "stylelint-config-twbs-bootstrap": "^14.0.0", + "ts-node": "^10.9.2", + "typescript": "^5.4.2" } } diff --git a/partials/AlertText.txt b/partials/AlertText.html similarity index 100% rename from partials/AlertText.txt rename to partials/AlertText.html diff --git a/partials/CollapsingRightSidebarContent.txt b/partials/CollapsingRightSidebarContent.html similarity index 97% rename from partials/CollapsingRightSidebarContent.txt rename to partials/CollapsingRightSidebarContent.html index 1db7e59b..5088a54f 100644 --- a/partials/CollapsingRightSidebarContent.txt +++ b/partials/CollapsingRightSidebarContent.html @@ -1,117 +1,117 @@ - - - - - -
- -
-
- - Unpacking Software Livestream - -

Join our monthly Unpacking Software livestream to hear about the latest news, chat and opinion on packaging, software deployment and lifecycle management!

- Learn More -
-
-
- - Chocolatey Product Spotlight - -

Join the Chocolatey Team on our regular monthly stream where we put a spotlight on the most recent Chocolatey product releases. You'll have a chance to have your questions answered in a live Ask Me Anything format.

- Learn More -
-
-
- - Chocolatey Coding Livestream - -

Join us for the Chocolatey Coding Livestream, where members of our team dive into the heart of open source development by coding live on various Chocolatey projects. Tune in to witness real-time coding, ask questions, and gain insights into the world of package management. Don't miss this opportunity to engage with our team and contribute to the future of Chocolatey!

- Learn More -
-
-
-
- - Calling All Chocolatiers! Whipping Up Windows Automation with Chocolatey Central Management - -

Webinar from
Wednesday, 17 January 2024

-

We are delighted to announce the release of Chocolatey Central Management v0.12.0, featuring seamless Deployment Plan creation, time-saving duplications, insightful Group Details, an upgraded Dashboard, bug fixes, user interface polishing, and refined documentation. As an added bonus we'll have members of our Solutions Engineering team on-hand to dive into some interesting ways you can leverage the new features available!

- Watch On-Demand -
-
-
- - Chocolatey Community Coffee Break - -

Join the Chocolatey Team as we discuss all things Community, what we do, how you can get involved and answer your Chocolatey questions.

- Watch The Replays -
-
-
- - Chocolatey and Intune Overview - -

Webinar Replay from
Wednesday, 30 March 2022

-

At Chocolatey Software we strive for simple, and teaching others. Let us teach you just how simple it could be to keep your 3rd party applications updated across your devices, all with Intune!

- Watch On-Demand -
-
-
- - Chocolatey For Business. In Azure. In One Click. - -

Livestream from
Thursday, 9 June 2022

-

Join James and Josh to show you how you can get the Chocolatey For Business recommended infrastructure and workflow, created, in Azure, in around 20 minutes.

- Watch On-Demand -
-
-
- - The Future of Chocolatey CLI - -

Livestream from
Thursday, 04 August 2022

-

Join Paul and Gary to hear more about the plans for the Chocolatey CLI in the not so distant future. We'll talk about some cool new features, long term asks from Customers and Community and how you can get involved!

- Watch On-Demand -
-
-
- - Hacktoberfest Tuesdays 2022 - -

Livestreams from
October 2022

-

For Hacktoberfest, Chocolatey ran a livestream every Tuesday! Re-watch Cory, James, Gary, and Rain as they share knowledge on how to contribute to open-source projects such as Chocolatey CLI.

- Watch On-Demand -
-
-
+ + + + + +
+ +
+
+ + Unpacking Software Livestream + +

Join our monthly Unpacking Software livestream to hear about the latest news, chat and opinion on packaging, software deployment and lifecycle management!

+ Learn More +
+
+
+ + Chocolatey Product Spotlight + +

Join the Chocolatey Team on our regular monthly stream where we put a spotlight on the most recent Chocolatey product releases. You'll have a chance to have your questions answered in a live Ask Me Anything format.

+ Learn More +
+
+
+ + Chocolatey Coding Livestream + +

Join us for the Chocolatey Coding Livestream, where members of our team dive into the heart of open source development by coding live on various Chocolatey projects. Tune in to witness real-time coding, ask questions, and gain insights into the world of package management. Don't miss this opportunity to engage with our team and contribute to the future of Chocolatey!

+ Learn More +
+
+
+
+ + Calling All Chocolatiers! Whipping Up Windows Automation with Chocolatey Central Management + +

Webinar from
Wednesday, 17 January 2024

+

We are delighted to announce the release of Chocolatey Central Management v0.12.0, featuring seamless Deployment Plan creation, time-saving duplications, insightful Group Details, an upgraded Dashboard, bug fixes, user interface polishing, and refined documentation. As an added bonus we'll have members of our Solutions Engineering team on-hand to dive into some interesting ways you can leverage the new features available!

+ Watch On-Demand +
+
+
+ + Chocolatey Community Coffee Break + +

Join the Chocolatey Team as we discuss all things Community, what we do, how you can get involved and answer your Chocolatey questions.

+ Watch The Replays +
+
+
+ + Chocolatey and Intune Overview + +

Webinar Replay from
Wednesday, 30 March 2022

+

At Chocolatey Software we strive for simple, and teaching others. Let us teach you just how simple it could be to keep your 3rd party applications updated across your devices, all with Intune!

+ Watch On-Demand +
+
+
+ + Chocolatey For Business. In Azure. In One Click. + +

Livestream from
Thursday, 9 June 2022

+

Join James and Josh to show you how you can get the Chocolatey For Business recommended infrastructure and workflow, created, in Azure, in around 20 minutes.

+ Watch On-Demand +
+
+
+ + The Future of Chocolatey CLI + +

Livestream from
Thursday, 04 August 2022

+

Join Paul and Gary to hear more about the plans for the Chocolatey CLI in the not so distant future. We'll talk about some cool new features, long term asks from Customers and Community and how you can get involved!

+ Watch On-Demand +
+
+
+ + Hacktoberfest Tuesdays 2022 + +

Livestreams from
October 2022

+

For Hacktoberfest, Chocolatey ran a livestream every Tuesday! Re-watch Cory, James, Gary, and Rain as they share knowledge on how to contribute to open-source projects such as Chocolatey CLI.

+ Watch On-Demand +
+
+
diff --git a/partials/globalnavigation.txt b/partials/GlobalNavigation.html similarity index 98% rename from partials/globalnavigation.txt rename to partials/GlobalNavigation.html index 3e5a5e69..c1fa622a 100644 --- a/partials/globalnavigation.txt +++ b/partials/GlobalNavigation.html @@ -1,12 +1,12 @@ -