diff --git a/.babelrc.js b/.babelrc.js
deleted file mode 100644
index 5139969..0000000
--- a/.babelrc.js
+++ /dev/null
@@ -1,12 +0,0 @@
-module.exports = {
- presets: [
- [
- '@babel/preset-env',
- {
- loose: true,
- bugfixes: true,
- modules: false
- }
- ]
- ]
-};
diff --git a/.browserslistrc b/.browserslistrc
deleted file mode 100644
index cddd230..0000000
--- a/.browserslistrc
+++ /dev/null
@@ -1,12 +0,0 @@
-# https://github.com/browserslist/browserslist#readme
-
->= 0.5%
-last 2 major versions
-not dead
-Chrome >= 60
-Firefox >= 60
-Firefox ESR
-iOS >= 12
-Safari >= 12
-not Explorer <= 11
-not kaios <= 2.5 # fix floating label issues in Firefox (see https://github.com/postcss/autoprefixer/issues/1533)
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 235ad54..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,45 +0,0 @@
-# Ignore docs files
-/_site/
-
-# Numerous always-ignore extensions
-*.diff
-*.err
-*.log
-*.orig
-*.rej
-*.swo
-*.swp
-*.vi
-*.zip
-*~
-
-# OS or Editor folders
-._*
-.cache
-.DS_Store
-.idea
-.project
-.settings
-.tmproj
-*.esproj
-*.sublime-project
-*.sublime-workspace
-nbproject
-Thumbs.db
-# Local Netlify folder
-.netlify
-
-# Komodo
-.komodotools
-*.komodoproject
-
-# Folders to ignore
-/dist-sass/
-/js/coverage/
-/node_modules/
-
-# Site
-/site/dist
-/site/node_modules
-/site/.astro
-/site/public
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 7562983..28fd5e8 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:
-- Demonstrating empathy and kindness toward other people
-- Being respectful of differing opinions, viewpoints, and experiences
-- Giving and gracefully accepting constructive feedback
-- Accepting responsibility and apologizing to those affected by our mistakes,
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
-- Focusing on what is best not just for us as individuals, but for the overall
+* Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
-- The use of sexualized language or imagery, and sexual attention or advances of
+* The use of sexualized language or imagery, and sexual attention or advances of
any kind
-- Trolling, insulting or derogatory comments, and personal or political attacks
-- Public or private harassment
-- Publishing others’ private information, such as a physical or email address,
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email address,
without their explicit permission
-- Other conduct which could reasonably be considered inappropriate in a
+* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
diff --git a/LICENSE b/LICENSE
index fa7c00b..dda75ca 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,7 @@
The MIT License (MIT)
-Copyright (c) 2011-2025 The Bootstrap Authors
+Copyright (c) 2011-2022 Twitter, Inc.
+Copyright (c) 2011-2022 The Bootstrap Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index e3618e6..bd40192 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-
+
@@ -9,13 +9,15 @@
Sleek, intuitive, and powerful front-end framework for faster and easier web development.
- Explore Bootstrap docs »
+ Explore Bootstrap docs »
Report bug
·
Request feature
·
+ Themes
+ ·
Blog
@@ -29,7 +31,7 @@ Our default branch is for development of our Bootstrap 5 release. Head to the [`
- [Quick start](#quick-start)
- [Status](#status)
-- [What’s included](#whats-included)
+- [What's included](#whats-included)
- [Bugs and feature requests](#bugs-and-feature-requests)
- [Documentation](#documentation)
- [Contributing](#contributing)
@@ -44,38 +46,37 @@ Our default branch is for development of our Bootstrap 5 release. Head to the [`
Several quick start options are available:
-- [Download the latest release](https://github.com/twbs/bootstrap/archive/v5.3.8.zip)
+- [Download the latest release](https://github.com/twbs/bootstrap/archive/v5.2.3.zip)
- Clone the repo: `git clone https://github.com/twbs/bootstrap.git`
-- Install with [npm](https://www.npmjs.com/): `npm install bootstrap@v5.3.8`
-- Install with [yarn](https://yarnpkg.com/): `yarn add bootstrap@v5.3.8`
-- Install with [Bun](https://bun.sh/): `bun add bootstrap@v5.3.8`
-- Install with [Composer](https://getcomposer.org/): `composer require twbs/bootstrap:5.3.8`
+- Install with [npm](https://www.npmjs.com/): `npm install bootstrap@v5.2.3`
+- Install with [yarn](https://yarnpkg.com/): `yarn add bootstrap@v5.2.3`
+- Install with [Composer](https://getcomposer.org/): `composer require twbs/bootstrap:5.2.3`
- Install with [NuGet](https://www.nuget.org/): CSS: `Install-Package bootstrap` Sass: `Install-Package bootstrap.sass`
-Read the [Getting started page](https://getbootstrap.com/docs/5.3/getting-started/introduction/) for information on the framework contents, templates, examples, and more.
+Read the [Getting started page](https://getbootstrap.com/docs/5.2/getting-started/introduction/) for information on the framework contents, templates, examples, and more.
## Status
-[](https://github.com/twbs/bootstrap/actions/workflows/js.yml?query=workflow%3AJS+branch%3Amain)
-[](https://www.npmjs.com/package/bootstrap)
-[](https://rubygems.org/gems/bootstrap)
-[](https://atmospherejs.com/twbs/bootstrap)
-[](https://packagist.org/packages/twbs/bootstrap)
-[](https://www.nuget.org/packages/bootstrap/absoluteLatest)
-[](https://coveralls.io/github/twbs/bootstrap?branch=main)
+[](https://github.com/twbs/bootstrap/actions?query=workflow%3AJS+Tests+branch%3Amain)
+[](https://www.npmjs.com/package/bootstrap)
+[](https://rubygems.org/gems/bootstrap)
+[](https://atmospherejs.com/twbs/bootstrap)
+[](https://packagist.org/packages/twbs/bootstrap)
+[](https://www.nuget.org/packages/bootstrap/absoluteLatest)
+[](https://coveralls.io/github/twbs/bootstrap?branch=main)
[](https://github.com/twbs/bootstrap/blob/main/dist/css/bootstrap.min.css)
[](https://github.com/twbs/bootstrap/blob/main/dist/css/bootstrap.min.css)
[](https://github.com/twbs/bootstrap/blob/main/dist/js/bootstrap.min.js)
[](https://github.com/twbs/bootstrap/blob/main/dist/js/bootstrap.min.js)
-
-[](#backers)
-[](#sponsors)
+[](https://www.browserstack.com/automate/public-build/SkxZcStBeExEdVJqQ2hWYnlWckpkNmNEY213SFp6WHFETWk2bGFuY3pCbz0tLXhqbHJsVlZhQnRBdEpod3NLSDMzaHc9PQ==--3d0b75245708616eb93113221beece33e680b229)
+[](#backers)
+[](#sponsors)
-## What’s included
+## What's included
-Within the download you’ll find the following directories and files, logically grouping common assets and providing both compiled and minified variations.
+Within the download you'll find the following directories and files, logically grouping common assets and providing both compiled and minified variations.
Download contents
@@ -131,7 +132,7 @@ Within the download you’ll find the following directories and files, logically
```
-We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). [Source maps](https://web.dev/articles/source-maps) (`bootstrap.*.map`) are available for use with certain browsers’ developer tools. Bundled JS files (`bootstrap.bundle.js` and minified `bootstrap.bundle.min.js`) include [Popper](https://popper.js.org/docs/v2/).
+We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). [Source maps](https://developers.google.com/web/tools/chrome-devtools/javascript/source-maps) (`bootstrap.*.map`) are available for use with certain browsers' developer tools. Bundled JS files (`bootstrap.bundle.js` and minified `bootstrap.bundle.min.js`) include [Popper](https://popper.js.org/).
## Bugs and feature requests
@@ -141,18 +142,18 @@ Have a bug or a feature request? Please first read the [issue guidelines](https:
## Documentation
-Bootstrap’s documentation, included in this repo in the root directory, is built with [Astro](https://astro.build/) and publicly hosted on GitHub Pages at . The docs may also be run locally.
+Bootstrap's documentation, included in this repo in the root directory, is built with [Hugo](https://gohugo.io/) and publicly hosted on GitHub Pages at . The docs may also be run locally.
-Documentation search is powered by [Algolia's DocSearch](https://docsearch.algolia.com/).
+Documentation search is powered by [Algolia's DocSearch](https://docsearch.algolia.com/). Working on our search? Be sure to set `debug: true` in `site/assets/js/search.js`.
### Running documentation locally
-1. Run `npm install` to install the Node.js dependencies, including Astro (the site builder).
+1. Run `npm install` to install the Node.js dependencies, including Hugo (the site builder).
2. Run `npm run test` (or a specific npm script) to rebuild distributed CSS and JavaScript files, as well as our docs assets.
3. From the root `/bootstrap` directory, run `npm run docs-serve` in the command line.
-4. Open in your browser, and voilà.
+4. Open `http://localhost:9001/` in your browser, and voilà.
-Learn more about using Astro by reading its [documentation](https://docs.astro.build/en/getting-started/).
+Learn more about using Hugo by reading its [documentation](https://gohugo.io/documentation/).
### Documentation for previous releases
@@ -172,12 +173,11 @@ Editor preferences are available in the [editor config](https://github.com/twbs/
## Community
-Get updates on Bootstrap’s development and chat with the project maintainers and community members.
+Get updates on Bootstrap's development and chat with the project maintainers and community members.
-- Follow [@getbootstrap on X](https://x.com/getbootstrap).
+- Follow [@getbootstrap on Twitter](https://twitter.com/getbootstrap).
- Read and subscribe to [The Official Bootstrap Blog](https://blog.getbootstrap.com/).
-- Ask questions and explore [our GitHub Discussions](https://github.com/twbs/bootstrap/discussions).
-- Discuss, ask questions, and more on [the community Discord](https://discord.gg/bZUvakRU3M) or [Bootstrap subreddit](https://www.reddit.com/r/bootstrap/).
+- Ask and explore [our GitHub Discussions](https://github.com/twbs/bootstrap/discussions).
- Chat with fellow Bootstrappers in IRC. On the `irc.libera.chat` server, in the `#bootstrap` channel.
- Implementation help may be found at Stack Overflow (tagged [`bootstrap-5`](https://stackoverflow.com/questions/tagged/bootstrap-5)).
- Developers should use the keyword `bootstrap` on packages which modify or add to the functionality of Bootstrap when distributing through [npm](https://www.npmjs.com/browse/keyword/bootstrap) or similar delivery mechanisms for maximum discoverability.
@@ -194,12 +194,12 @@ See [the Releases section of our GitHub project](https://github.com/twbs/bootstr
**Mark Otto**
--
+-
-
**Jacob Thornton**
--
+-
-
@@ -243,4 +243,4 @@ Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com
## Copyright and license
-Code and documentation copyright 2011-2025 the [Bootstrap Authors](https://github.com/twbs/bootstrap/graphs/contributors). Code released under the [MIT License](https://github.com/twbs/bootstrap/blob/main/LICENSE). Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/).
+Code and documentation copyright 2011–2022 the [Bootstrap Authors](https://github.com/twbs/bootstrap/graphs/contributors) and [Twitter, Inc.](https://twitter.com) Code released under the [MIT License](https://github.com/twbs/bootstrap/blob/main/LICENSE). Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/).
diff --git a/build/.eslintrc.json b/build/.eslintrc.json
new file mode 100644
index 0000000..dec6323
--- /dev/null
+++ b/build/.eslintrc.json
@@ -0,0 +1,15 @@
+{
+ "env": {
+ "browser": false,
+ "node": true
+ },
+ "parserOptions": {
+ "sourceType": "script"
+ },
+ "extends": "../.eslintrc.json",
+ "rules": {
+ "no-console": "off",
+ "strict": "error",
+ "unicorn/prefer-top-level-await": "off"
+ }
+}
diff --git a/build/banner.mjs b/build/banner.js
similarity index 50%
rename from build/banner.mjs
rename to build/banner.js
index 3fea93c..df82ff3 100644
--- a/build/banner.mjs
+++ b/build/banner.js
@@ -1,12 +1,6 @@
-import fs from 'node:fs/promises'
-import path from 'node:path'
-import { fileURLToPath } from 'node:url'
-
-const __dirname = path.dirname(fileURLToPath(import.meta.url))
-
-const pkgJson = path.join(__dirname, '../package.json')
-const pkg = JSON.parse(await fs.readFile(pkgJson, 'utf8'))
+'use strict'
+const pkg = require('../package.json')
const year = new Date().getFullYear()
function getBanner(pluginFilename) {
@@ -17,4 +11,4 @@ function getBanner(pluginFilename) {
*/`
}
-export default getBanner
+module.exports = getBanner
diff --git a/build/build-plugins.mjs b/build/build-plugins.js
similarity index 82%
rename from build/build-plugins.mjs
rename to build/build-plugins.js
index f56cd21..a160209 100644
--- a/build/build-plugins.mjs
+++ b/build/build-plugins.js
@@ -2,22 +2,21 @@
/*!
* Script to build our plugins to use them separately.
- * Copyright 2020-2025 The Bootstrap Authors
+ * Copyright 2020-2022 The Bootstrap Authors
+ * Copyright 2020-2022 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
-import path from 'node:path'
-import { fileURLToPath } from 'node:url'
-import { babel } from '@rollup/plugin-babel'
-import { globby } from 'globby'
-import { rollup } from 'rollup'
-import banner from './banner.mjs'
+'use strict'
-const __filename = fileURLToPath(import.meta.url)
-const __dirname = path.dirname(fileURLToPath(import.meta.url))
+const path = require('node:path')
+const rollup = require('rollup')
+const globby = require('globby')
+const { babel } = require('@rollup/plugin-babel')
+const banner = require('./banner.js')
const sourcePath = path.resolve(__dirname, '../js/src/').replace(/\\/g, '/')
-const jsFiles = await globby(`${sourcePath}/**/*.js`)
+const jsFiles = globby.sync(sourcePath + '/**/*.js')
// Array which holds the resolved plugins
const resolvedPlugins = []
@@ -28,7 +27,7 @@ const filenameToEntity = filename => filename.replace('.js', '')
for (const file of jsFiles) {
resolvedPlugins.push({
- src: file,
+ src: file.replace('.js', ''),
dist: file.replace('src', 'dist'),
fileName: path.basename(file),
className: filenameToEntity(path.basename(file))
@@ -37,12 +36,9 @@ for (const file of jsFiles) {
}
const build = async plugin => {
- /**
- * @type {import('rollup').GlobalsOption}
- */
const globals = {}
- const bundle = await rollup({
+ const bundle = await rollup.rollup({
input: plugin.src,
plugins: [
babel({
diff --git a/build/change-version.js b/build/change-version.js
new file mode 100644
index 0000000..57c5fde
--- /dev/null
+++ b/build/change-version.js
@@ -0,0 +1,81 @@
+#!/usr/bin/env node
+
+/*!
+ * Script to update version number references in the project.
+ * Copyright 2017-2022 The Bootstrap Authors
+ * Copyright 2017-2022 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ */
+
+'use strict'
+
+const fs = require('node:fs').promises
+const path = require('node:path')
+const globby = require('globby')
+
+const VERBOSE = process.argv.includes('--verbose')
+const DRY_RUN = process.argv.includes('--dry') || process.argv.includes('--dry-run')
+
+// These are the filetypes we only care about replacing the version
+const GLOB = [
+ '**/*.{css,html,js,json,md,scss,txt,yml}'
+]
+const GLOBBY_OPTIONS = {
+ cwd: path.join(__dirname, '..'),
+ gitignore: true
+}
+
+// Blame TC39... https://github.com/benjamingr/RegExp.escape/issues/37
+function regExpQuote(string) {
+ return string.replace(/[$()*+-.?[\\\]^{|}]/g, '\\$&')
+}
+
+function regExpQuoteReplacement(string) {
+ return string.replace(/\$/g, '$$')
+}
+
+async function replaceRecursively(file, oldVersion, newVersion) {
+ const originalString = await fs.readFile(file, 'utf8')
+ const newString = originalString.replace(
+ new RegExp(regExpQuote(oldVersion), 'g'), regExpQuoteReplacement(newVersion)
+ )
+
+ // No need to move any further if the strings are identical
+ if (originalString === newString) {
+ return
+ }
+
+ if (VERBOSE) {
+ console.log(`FILE: ${file}`)
+ }
+
+ if (DRY_RUN) {
+ return
+ }
+
+ await fs.writeFile(file, newString, 'utf8')
+}
+
+async function main(args) {
+ let [oldVersion, newVersion] = args
+
+ if (!oldVersion || !newVersion) {
+ console.error('USAGE: change-version old_version new_version [--verbose] [--dry[-run]]')
+ console.error('Got arguments:', args)
+ process.exit(1)
+ }
+
+ // Strip any leading `v` from arguments because otherwise we will end up with duplicate `v`s
+ [oldVersion, newVersion] = [oldVersion, newVersion].map(arg => arg.startsWith('v') ? arg.slice(1) : arg)
+
+ try {
+ const files = await globby(GLOB, GLOBBY_OPTIONS)
+
+ await Promise.all(files.map(file => replaceRecursively(file, oldVersion, newVersion)))
+ } catch (error) {
+ console.error(error)
+ process.exit(1)
+ }
+}
+
+main(process.argv.slice(2))
diff --git a/build/change-version.mjs b/build/change-version.mjs
deleted file mode 100644
index 1400274..0000000
--- a/build/change-version.mjs
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/usr/bin/env node
-
-/*!
- * Script to update version number references in the project.
- * Copyright 2017-2025 The Bootstrap Authors
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
- */
-
-import { execFile } from 'node:child_process'
-import fs from 'node:fs/promises'
-import process from 'node:process'
-
-const VERBOSE = process.argv.includes('--verbose')
-const DRY_RUN = process.argv.includes('--dry') || process.argv.includes('--dry-run')
-
-// These are the files we only care about replacing the version
-const FILES = [
- 'README.md',
- 'config.yml',
- 'js/src/base-component.js',
- 'package.js',
- 'scss/mixins/_banner.scss',
- 'site/data/docs-versions.yml'
-]
-
-// Blame TC39... https://github.com/benjamingr/RegExp.escape/issues/37
-function regExpQuote(string) {
- return string.replace(/[$()*+-.?[\\\]^{|}]/g, '\\$&')
-}
-
-function regExpQuoteReplacement(string) {
- return string.replace(/\$/g, '$$')
-}
-
-async function replaceRecursively(file, oldVersion, newVersion) {
- const originalString = await fs.readFile(file, 'utf8')
- const newString = originalString
- .replace(
- new RegExp(regExpQuote(oldVersion), 'g'),
- regExpQuoteReplacement(newVersion)
- )
- // Also replace the version used by the rubygem,
- // which is using periods (`.`) instead of hyphens (`-`)
- .replace(
- new RegExp(regExpQuote(oldVersion.replace(/-/g, '.')), 'g'),
- regExpQuoteReplacement(newVersion.replace(/-/g, '.'))
- )
-
- // No need to move any further if the strings are identical
- if (originalString === newString) {
- return
- }
-
- if (VERBOSE) {
- console.log(`Found ${oldVersion} in ${file}`)
- }
-
- if (DRY_RUN) {
- return
- }
-
- await fs.writeFile(file, newString, 'utf8')
-}
-
-function bumpNpmVersion(newVersion) {
- if (DRY_RUN) {
- return
- }
-
- execFile('npm', ['version', newVersion, '--no-git-tag'], { shell: true }, error => {
- if (error) {
- console.error(error)
- process.exit(1)
- }
- })
-}
-
-function showUsage(args) {
- console.error('USAGE: change-version old_version new_version [--verbose] [--dry[-run]]')
- console.error('Got arguments:', args)
- process.exit(1)
-}
-
-async function main(args) {
- 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)
- }
-
- bumpNpmVersion(newVersion)
-
- try {
- await Promise.all(
- FILES.map(file => replaceRecursively(file, oldVersion, newVersion))
- )
- } catch (error) {
- console.error(error)
- process.exit(1)
- }
-}
-
-main(process.argv.slice(2))
diff --git a/build/docs-prep.sh b/build/docs-prep.sh
deleted file mode 100755
index 357768a..0000000
--- a/build/docs-prep.sh
+++ /dev/null
@@ -1,157 +0,0 @@
-#!/bin/bash
-
-# Colors for output
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[0;33m'
-BLUE='\033[0;34m'
-NC='\033[0m' # No Color
-
-# Default branch suffix
-BRANCH_SUFFIX="release"
-
-# Check if a custom version parameter was provided
-if [ $# -eq 1 ]; then
- BRANCH_SUFFIX="$1"
-fi
-
-# Branch name to create
-NEW_BRANCH="gh-pages-${BRANCH_SUFFIX}"
-
-# Get the current docs version from config
-DOCS_VERSION=$(node -p "require('js-yaml').load(require('fs').readFileSync('config.yml', 'utf8')).docs_version")
-
-# Function to print colored messages
-print_success() {
- echo -e "${GREEN}✓ $1${NC}"
-}
-
-print_error() {
- echo -e "${RED}✗ $1${NC}"
- exit 1
-}
-
-print_info() {
- echo -e "${BLUE}ℹ $1${NC}"
-}
-
-print_warning() {
- echo -e "${YELLOW}⚠ $1${NC}"
-}
-
-# Function to execute command with error handling
-execute() {
- print_info "Running: $1"
- eval $1
- if [ $? -ne 0 ]; then
- print_error "Failed to execute: $1"
- else
- print_success "Successfully executed: $1"
- fi
-}
-
-# Check if /tmp/_site directory exists from a previous run
-if [ -d "/tmp/_site" ]; then
- print_warning "Found existing /tmp/_site directory. Removing it…"
- rm -rf /tmp/_site
-fi
-
-# Main process
-print_info "Starting documentation deployment process…"
-
-# Step 1: Build documentation
-print_info "Building documentation with npm run docs…"
-npm run docs
-if [ $? -ne 0 ]; then
- print_error "Documentation build failed!"
-fi
-print_success "Documentation built successfully"
-
-# Step 2: Move _site to /tmp/
-print_info "Moving _site to temporary location…"
-execute "mv _site /tmp/"
-
-# Step 3: Switch to gh-pages branch
-print_info "Checking out gh-pages branch…"
-git checkout gh-pages
-if [ $? -ne 0 ]; then
- print_error "Failed to checkout gh-pages branch. Make sure it exists."
-fi
-print_success "Switched to gh-pages branch"
-
-git reset --hard origin/gh-pages
-if [ $? -ne 0 ]; then
- print_error "Failed to reset to origin/gh-pages. Check your git configuration."
-fi
-print_success "Reset to origin/gh-pages"
-
-git pull origin gh-pages
-if [ $? -ne 0 ]; then
- print_error "Failed to pull from origin/gh-pages. Check your network connection and git configuration."
-fi
-print_success "Pulled latest changes from origin/gh-pages"
-
-# Step 4: Create a new branch for the update
-print_info "Checking if branch ${NEW_BRANCH} exists and deleting it if it does…"
-if git show-ref --verify --quiet refs/heads/${NEW_BRANCH}; then
- execute "git branch -D ${NEW_BRANCH}"
-else
- print_info "Branch ${NEW_BRANCH} does not exist, proceeding with creation…"
-fi
-print_info "Creating new branch ${NEW_BRANCH}…"
-execute "git checkout -b ${NEW_BRANCH}"
-
-# Step 5: Move all root-level files from Astro build
-find /tmp/_site -maxdepth 1 -type f -exec mv {} . \;
-
-# Step 6: Move all top-level directories except 'docs' (which needs special handling)
-find /tmp/_site -maxdepth 1 -type d ! -name "_site" ! -name "docs" -exec sh -c 'dir=$(basename "$1"); rm -rf "$dir"; mv "$1" .' _ {} \;
-
-# Step 7: Handle docs directory specially
-if [ -d "/tmp/_site/docs" ]; then
- # Replace only the current version's docs
- if [ -d "docs/$DOCS_VERSION" ]; then
- rm -rf "docs/$DOCS_VERSION"
- fi
- mv "/tmp/_site/docs/$DOCS_VERSION" "docs/"
-
- # Handle docs root files
- find /tmp/_site/docs -maxdepth 1 -type f -exec mv {} docs/ \;
-
- # Handle special docs directories (getting-started, versions)
- for special_dir in getting-started versions; do
- if [ -d "/tmp/_site/docs/$special_dir" ]; then
- rm -rf "docs/$special_dir"
- mv "/tmp/_site/docs/$special_dir" "docs/"
- fi
- done
-fi
-
-# Clean up remaining files in /tmp/_site if any
-if [ -d "/tmp/_site" ]; then
- remaining_files=$(find /tmp/_site -type f | wc -l)
- remaining_dirs=$(find /tmp/_site -type d | wc -l)
- if [ $remaining_files -gt 0 ] || [ $remaining_dirs -gt 1 ]; then
- print_warning "There are still some files or directories in /tmp/_site that weren't moved."
- print_warning "You may want to inspect /tmp/_site to see if anything important was missed."
- else
- print_info "Cleaning up temporary directory…"
- rm -rf /tmp/_site
- print_success "Temporary directory cleaned up"
- fi
-fi
-
-# Step 10: Remove empty site directory if it exists
-if [ -d "site" ]; then
- print_info "Removing empty site directory…"
- execute "rm -rf site"
-fi
-
-print_success "Docs prep complete!"
-print_info "Review changes before committing and pushing."
-print_info "Next steps:"
-print_info " 1. Run a local server to review changes"
-print_info " 2. Check browser and web inspector for any errors"
-print_info " 3. git add ."
-print_info " 4. git commit -m \"Update documentation\""
-print_info " 5. git push origin ${NEW_BRANCH}"
diff --git a/build/generate-sri.mjs b/build/generate-sri.js
similarity index 60%
rename from build/generate-sri.mjs
rename to build/generate-sri.js
index 5622843..ef1b39f 100644
--- a/build/generate-sri.mjs
+++ b/build/generate-sri.js
@@ -5,17 +5,17 @@
* Remember to use the same vendor files as the CDN ones,
* otherwise the hashes won't match!
*
- * Copyright 2017-2025 The Bootstrap Authors
+ * Copyright 2017-2022 The Bootstrap Authors
+ * Copyright 2017-2022 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
-import crypto from 'node:crypto'
-import fs from 'node:fs'
-import path from 'node:path'
-import { fileURLToPath } from 'node:url'
-import sh from 'shelljs'
+'use strict'
-const __dirname = path.dirname(fileURLToPath(import.meta.url))
+const crypto = require('node:crypto')
+const fs = require('node:fs')
+const path = require('node:path')
+const sh = require('shelljs')
sh.config.fatal = true
@@ -47,18 +47,18 @@ const files = [
}
]
-for (const { file, configPropertyName } of files) {
- fs.readFile(file, 'utf8', (error, data) => {
+for (const file of files) {
+ fs.readFile(file.file, 'utf8', (error, data) => {
if (error) {
throw error
}
- const algorithm = 'sha384'
- const hash = crypto.createHash(algorithm).update(data, 'utf8').digest('base64')
- const integrity = `${algorithm}-${hash}`
+ const algo = 'sha384'
+ const hash = crypto.createHash(algo).update(data, 'utf8').digest('base64')
+ const integrity = `${algo}-${hash}`
- console.log(`${configPropertyName}: ${integrity}`)
+ console.log(`${file.configPropertyName}: ${integrity}`)
- sh.sed('-i', new RegExp(`^(\\s+${configPropertyName}:\\s+["'])\\S*(["'])`), `$1${integrity}$2`, configFile)
+ sh.sed('-i', new RegExp(`^(\\s+${file.configPropertyName}:\\s+["'])\\S*(["'])`), `$1${integrity}$2`, configFile)
})
}
diff --git a/build/postcss.config.mjs b/build/postcss.config.js
similarity index 86%
rename from build/postcss.config.mjs
rename to build/postcss.config.js
index 7717cfc..7f8186d 100644
--- a/build/postcss.config.mjs
+++ b/build/postcss.config.js
@@ -1,10 +1,12 @@
+'use strict'
+
const mapConfig = {
inline: false,
annotation: true,
sourcesContent: true
}
-export default context => {
+module.exports = context => {
return {
map: context.file.dirname.includes('examples') ? false : mapConfig,
plugins: {
diff --git a/build/rollup.config.mjs b/build/rollup.config.js
similarity index 62%
rename from build/rollup.config.mjs
rename to build/rollup.config.js
index dd6c7d1..27f12ac 100644
--- a/build/rollup.config.mjs
+++ b/build/rollup.config.js
@@ -1,17 +1,15 @@
-import path from 'node:path'
-import process from 'node:process'
-import { fileURLToPath } from 'node:url'
-import { babel } from '@rollup/plugin-babel'
-import { nodeResolve } from '@rollup/plugin-node-resolve'
-import replace from '@rollup/plugin-replace'
-import banner from './banner.mjs'
+'use strict'
-const __dirname = path.dirname(fileURLToPath(import.meta.url))
+const path = require('node:path')
+const { babel } = require('@rollup/plugin-babel')
+const { nodeResolve } = require('@rollup/plugin-node-resolve')
+const replace = require('@rollup/plugin-replace')
+const banner = require('./banner.js')
const BUNDLE = process.env.BUNDLE === 'true'
const ESM = process.env.ESM === 'true'
-let destinationFile = `bootstrap${ESM ? '.esm' : ''}`
+let fileDestination = `bootstrap${ESM ? '.esm' : ''}`
const external = ['@popperjs/core']
const plugins = [
babel({
@@ -26,7 +24,7 @@ const globals = {
}
if (BUNDLE) {
- destinationFile += '.bundle'
+ fileDestination += '.bundle'
// Remove last entry in external array to bundle Popper
external.pop()
delete globals['@popperjs/core']
@@ -42,8 +40,8 @@ if (BUNDLE) {
const rollupConfig = {
input: path.resolve(__dirname, `../js/index.${ESM ? 'esm' : 'umd'}.js`),
output: {
- banner: banner(),
- file: path.resolve(__dirname, `../dist/js/${destinationFile}.js`),
+ banner,
+ file: path.resolve(__dirname, `../dist/js/${fileDestination}.js`),
format: ESM ? 'esm' : 'umd',
globals,
generatedCode: 'es2015'
@@ -56,4 +54,4 @@ if (!ESM) {
rollupConfig.output.name = 'bootstrap'
}
-export default rollupConfig
+module.exports = rollupConfig
diff --git a/build/vnu-jar.mjs b/build/vnu-jar.js
similarity index 64%
rename from build/vnu-jar.mjs
rename to build/vnu-jar.js
index 4eedb1b..f29eeb7 100644
--- a/build/vnu-jar.mjs
+++ b/build/vnu-jar.js
@@ -2,22 +2,22 @@
/*!
* Script to run vnu-jar if Java is available.
- * Copyright 2017-2025 The Bootstrap Authors
+ * Copyright 2017-2022 The Bootstrap Authors
+ * Copyright 2017-2022 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
-import { execFile, spawn } from 'node:child_process'
-import vnu from 'vnu-jar'
+'use strict'
+
+const { execFile, spawn } = require('node:child_process')
+const vnu = require('vnu-jar')
execFile('java', ['-version'], (error, stdout, stderr) => {
if (error) {
- console.error('Skipping vnu-jar test; Java is probably missing.')
- console.error(error)
+ console.error('Skipping vnu-jar test; Java is missing.')
return
}
- console.log('Running vnu-jar validation...')
-
const is32bitJava = !/64-Bit/.test(stderr)
// vnu-jar accepts multiple ignores joined with a `|`.
@@ -30,14 +30,7 @@ execFile('java', ['-version'], (error, stdout, stderr) => {
// Per https://www.w3.org/TR/html-aria/#docconformance having "aria-disabled" on a link is
// NOT RECOMMENDED, but it's still valid - we explain in the docs that it's not ideal,
// and offer more robust alternatives, but also need to show a less-than-ideal example
- 'An “aria-disabled” attribute whose value is “true” should not be specified on an “a” element that has an “href” attribute.',
- // A `code` element with the `is:raw` attribute coming from remark-prismjs (Astro upstream possible bug)
- 'Attribute “is:raw” is not serializable as XML 1.0.',
- 'Attribute “is:raw” not allowed on element “code” at this point.',
- // Astro's expecting trailing slashes on HTML tags such as
- 'Trailing slash on void elements has no effect and interacts badly with unquoted attribute values.',
- // Allow `switch` attribute.
- 'Attribute “switch” not allowed on element “input” at this point.'
+ 'An “aria-disabled” attribute whose value is “true” should not be specified on an “a” element that has an “href” attribute.'
].join('|')
const args = [
@@ -56,8 +49,6 @@ execFile('java', ['-version'], (error, stdout, stderr) => {
args.splice(0, 0, '-Xss512k')
}
- console.log(`command used: java ${args.join(' ')}`)
-
return spawn('java', args, {
shell: true,
stdio: 'inherit'
diff --git a/build/zip-examples.mjs b/build/zip-examples.js
similarity index 57%
rename from build/zip-examples.mjs
rename to build/zip-examples.js
index 6b2e1e0..077901e 100644
--- a/build/zip-examples.mjs
+++ b/build/zip-examples.js
@@ -3,20 +3,16 @@
/*!
* Script to create the built examples zip archive;
* requires the `zip` command to be present!
- * Copyright 2020-2025 The Bootstrap Authors
+ * Copyright 2020-2022 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
-import fs from 'node:fs/promises'
-import path from 'node:path'
-import { fileURLToPath } from 'node:url'
-import sh from 'shelljs'
-import { format } from 'prettier'
+'use strict'
-const __dirname = path.dirname(fileURLToPath(import.meta.url))
+const path = require('node:path')
+const sh = require('shelljs')
-const pkgJson = path.join(__dirname, '../package.json')
-const pkg = JSON.parse(await fs.readFile(pkgJson, 'utf8'))
+const pkg = require('../package.json')
const versionShort = pkg.config.version_short
const distFolder = `bootstrap-${pkg.version}-examples`
@@ -38,9 +34,6 @@ const imgFiles = [
'bootstrap-logo.svg',
'bootstrap-logo-white.svg'
]
-const staticJsFiles = [
- 'color-modes.js'
-]
sh.config.fatal = true
@@ -59,8 +52,7 @@ sh.mkdir('-p', [
distFolder,
`${distFolder}/assets/brand/`,
`${distFolder}/assets/dist/css/`,
- `${distFolder}/assets/dist/js/`,
- `${distFolder}/assets/js/`
+ `${distFolder}/assets/dist/js/`
])
sh.cp('-Rf', `${docsDir}/examples/*`, distFolder)
@@ -77,44 +69,22 @@ for (const file of imgFiles) {
sh.cp('-f', `${docsDir}/assets/brand/${file}`, `${distFolder}/assets/brand/`)
}
-for (const file of staticJsFiles) {
- sh.cp('-f', `${docsDir}/assets/js/${file}`, `${distFolder}/assets/js/`)
-}
-
sh.rm(`${distFolder}/index.html`)
// get all examples' HTML files
-const htmlFiles = sh.find(`${distFolder}/**/*.html`)
-
-const formatPromises = htmlFiles.map(async file => {
+for (const file of sh.find(`${distFolder}/**/*.html`)) {
const fileContents = sh.cat(file)
.toString()
.replace(new RegExp(`"/docs/${versionShort}/`, 'g'), '"../')
.replace(/"..\/dist\//g, '"../assets/dist/')
- .replace(/( ]*) integrity="[^"]*"/g, '$1')
- .replace(/ ]*href="\.\.\/assets\/img\/favicons\/[^"]*"[^>]*>/g, '')
- .replace(/(')
+ .replace(/( +)