Compare commits
32 Commits
main
..
v6-rm-dist
| Author | SHA1 | Date | |
|---|---|---|---|
| 025fd1addc | |||
| 5dd5bac54a | |||
| aaf730a893 | |||
| dd579b3636 | |||
| a4af8c3fcf | |||
| ce2cca8601 | |||
| 387ea724ee | |||
| 4fecde40b8 | |||
| 5a54f29ae3 | |||
| f9c8e96f70 | |||
| f0c163b917 | |||
| 956de4bbaf | |||
| c8e8d28d29 | |||
| 482b0eb333 | |||
| e5a1ee3d3a | |||
| 21491d1f2f | |||
| 98d6c80cd9 | |||
| 5f910f4a09 | |||
| 484c4357ea | |||
| 334d68b75a | |||
| dbf36bbd01 | |||
| 062e7425b8 | |||
| ae01f064b0 | |||
| c0f88d638a | |||
| ca74fc29fd | |||
| 85adb49027 | |||
| f1edacb405 | |||
| 96491cf5c8 | |||
| ff14a64d2d | |||
| ea8523a4f4 | |||
| 1d3d4339ba | |||
| 37d69e7c38 |
@@ -2,35 +2,35 @@
|
||||
"files": [
|
||||
{
|
||||
"path": "./dist/css/bootstrap-grid.css",
|
||||
"maxSize": "6.5 kB"
|
||||
"maxSize": "9.00 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap-grid.min.css",
|
||||
"maxSize": "6.0 kB"
|
||||
"maxSize": "8.25 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap-reboot.css",
|
||||
"maxSize": "3.5 kB"
|
||||
"maxSize": "5.0 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap-reboot.min.css",
|
||||
"maxSize": "3.25 kB"
|
||||
"maxSize": "4.5 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap-utilities.css",
|
||||
"maxSize": "11.75 kB"
|
||||
"maxSize": "13.5 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap-utilities.min.css",
|
||||
"maxSize": "10.75 kB"
|
||||
"maxSize": "12.0 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap.css",
|
||||
"maxSize": "32.5 kB"
|
||||
"maxSize": "36.5 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap.min.css",
|
||||
"maxSize": "30.25 kB"
|
||||
"maxSize": "33.0 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/bootstrap.bundle.js",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"callout",
|
||||
"callouts",
|
||||
"camelCase",
|
||||
"checkgroup",
|
||||
"clearfix",
|
||||
"Codesniffer",
|
||||
"combinator",
|
||||
@@ -29,6 +30,7 @@
|
||||
"Crossfade",
|
||||
"crossfading",
|
||||
"cssgrid",
|
||||
"csstricks",
|
||||
"Csvg",
|
||||
"Datalists",
|
||||
"Deque",
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
# Incident response plan
|
||||
|
||||
This document describes how the Bootstrap maintainers respond to and manage security or operational incidents affecting the project, its website, or its distributed releases. This plan is public to promote transparency and community trust. Operational details (e.g., private contacts, credentials, or internal coordination tools) are maintained separately in the maintainers’ private documentation.
|
||||
|
||||
---
|
||||
|
||||
## 1. Purpose & Scope
|
||||
|
||||
This plan defines how Bootstrap maintainers will:
|
||||
|
||||
- Identify, triage, and manage security or integrity incidents affecting project code, releases, or infrastructure.
|
||||
- Communicate with the community and downstream consumers during and after an incident.
|
||||
- Record lessons learned and update processes to reduce future risk.
|
||||
|
||||
It applies to:
|
||||
|
||||
- The Bootstrap source code, documentation, and build pipelines.
|
||||
- Release artifacts (npm, CDN, GitHub releases).
|
||||
- The main website ([https://getbootstrap.com](https://getbootstrap.com)).
|
||||
- Any official Bootstrap GitHub organization infrastructure.
|
||||
|
||||
It does **not** cover unrelated third-party forks or integrations.
|
||||
|
||||
---
|
||||
|
||||
## 2. Definitions
|
||||
|
||||
- **Incident**: Any event that could compromise the confidentiality, integrity, or availability of Bootstrap code, releases, or users. Examples include:
|
||||
- A discovered security vulnerability.
|
||||
- A compromised GitHub account or CI/CD token.
|
||||
- A malicious dependency or injected code in a release.
|
||||
- Website defacement or unauthorized modification of documentation.
|
||||
- Leaked secrets related to the project infrastructure.
|
||||
|
||||
- **Incident Commander (IC)**: The maintainer responsible for coordinating the overall response.
|
||||
|
||||
---
|
||||
|
||||
## 3. Roles & Responsibilities
|
||||
|
||||
| Role | Responsibilities |
|
||||
|------|-------------------|
|
||||
| **Incident Commander (IC)** | Coordinate the response, assign tasks, ensure timely communication. |
|
||||
| **Security Maintainers** | Triage reported vulnerabilities, assess impact, create fixes, handle embargoes. |
|
||||
| **Infrastructure Lead** | Manage CI/CD, website, and release infrastructure. |
|
||||
| **Communications Lead** | Manage public announcements, blog posts, and social updates. |
|
||||
| **Contributors & Community** | Promptly report suspected security issues and follow responsible disclosure guidelines. |
|
||||
|
||||
In practice, Bootstrap’s core team fulfills these roles collectively, assigning an IC on a per-incident basis.
|
||||
|
||||
---
|
||||
|
||||
## 4. Incident workflow
|
||||
|
||||
### 4.1 Detection & Reporting
|
||||
|
||||
- All security issues should be **privately reported** via the contact method in [`SECURITY.md`](../SECURITY.md) or through GitHub’s Security Advisory mechanism.
|
||||
- Maintainers also monitor:
|
||||
- Automated dependency scanners (e.g., Dependabot, npm audit).
|
||||
- GitHub notifications and vulnerability alerts.
|
||||
- Community channels for suspicious activity.
|
||||
|
||||
### 4.2 Initial triage
|
||||
|
||||
Upon receiving a report:
|
||||
|
||||
1. A maintainer acknowledges receipt within 3 business days (or sooner, when possible).
|
||||
Bootstrap is maintained by a small volunteer team; response times may vary slightly outside normal working hours.
|
||||
2. The IC assesses severity and impact:
|
||||
- **Critical:** immediate compromise of release infrastructure or code integrity.
|
||||
- **High:** exploitable vulnerability in distributed assets.
|
||||
- **Medium:** minor vulnerability or low-likelihood attack vector.
|
||||
- **Low:** informational, no direct risk.
|
||||
3. If confirmed as an incident, the IC opens a private coordination channel for maintainers and begins containment.
|
||||
|
||||
### 4.3 Containment & Eradication
|
||||
|
||||
- Revoke or rotate any affected credentials.
|
||||
- Disable compromised infrastructure or build pipelines if necessary.
|
||||
- Patch affected branches or dependencies.
|
||||
- Verify integrity of artifacts and releases.
|
||||
|
||||
### 4.4 Communication
|
||||
|
||||
- Keep the reporting party informed (when applicable).
|
||||
- For major incidents, the Communications Lead drafts a public advisory describing:
|
||||
- What happened
|
||||
- What was impacted
|
||||
- How users can verify or mitigate
|
||||
- What actions were taken
|
||||
- Communications occur after containment to avoid amplifying risk.
|
||||
|
||||
Public disclosures are posted via:
|
||||
|
||||
- GitHub Security Advisory if appropriate
|
||||
- [blog.getbootstrap.com/](https://blog.getbootstrap.com/)
|
||||
- [Bootstrap GitHub discussions](https://github.com/orgs/twbs/discussions)
|
||||
- [@getbootstrap](https://x.com/getbootstrap) on X (formerly Twitter) for critical security notices.
|
||||
|
||||
### 4.5 Recovery
|
||||
|
||||
- Validate all systems and releases are secure.
|
||||
- Resume normal operations.
|
||||
- Tag patched releases and notify affected users.
|
||||
|
||||
### 4.6 Post-incident review
|
||||
|
||||
Within two weeks after resolution:
|
||||
|
||||
- Conduct an internal debrief.
|
||||
- Record:
|
||||
- Root cause
|
||||
- What worked / what didn’t
|
||||
- Remediation steps
|
||||
- Documentation or automation updates needed
|
||||
- Summarize lessons learned in the private maintainers’ wiki (with optional public summary if appropriate).
|
||||
|
||||
---
|
||||
|
||||
## 5. Severity levels & Response targets
|
||||
|
||||
| Severity | Example | Target response (volunteer team) |
|
||||
|-----------|----------|----------------------------------|
|
||||
| **Critical** | Compromised release, stolen signing keys | Acknowledge ≤ 24h (best effort), containment ≤ 48h, fix ideally ≤ 14d |
|
||||
| **High** | Vulnerability enabling arbitrary code execution | Acknowledge ≤ 3 business days, fix ideally ≤ 14–21d |
|
||||
| **Medium** | XSS or content injection on docs site | Acknowledge ≤ 5 business days, fix in next release cycle |
|
||||
| **Low** | Minor issue with limited risk | Acknowledge ≤ 7 business days, fix as scheduled |
|
||||
|
||||
**Note:** Timelines represent good-faith targets for a small volunteer core team, not hard SLAs. The maintainers will always prioritize public safety and transparency, even if timing varies.
|
||||
|
||||
---
|
||||
|
||||
## 6. Public disclosure principles
|
||||
|
||||
Bootstrap follows a responsible disclosure approach:
|
||||
|
||||
- Work privately with reporters and affected parties before publishing details.
|
||||
- Never name reporters without consent.
|
||||
- Coordinate embargo periods with downstream consumers when needed.
|
||||
- Publish advisories only after patches or mitigations are available.
|
||||
|
||||
---
|
||||
|
||||
## 7. Communication Channels
|
||||
|
||||
| Purpose | Channel |
|
||||
|----------|----------|
|
||||
| Private reporting | Email address in [`SECURITY.md`](./SECURITY.md) or GitHub advisory form |
|
||||
| General updates | [blog.getbootstrap.com/](https://blog.getbootstrap.com/) blog |
|
||||
| Security advisories | GitHub Security Advisory dashboard |
|
||||
| Social alerts | [@getbootstrap](https://x.com/getbootstrap) |
|
||||
| GitHub discussion alerts | [github.com/orgs/twbs/discussions](https://github.com/orgs/twbs/discussions) |
|
||||
|
||||
---
|
||||
|
||||
## 8. Plan Maintenance
|
||||
|
||||
This plan is reviewed at least annually or after any major incident. Changes are approved by the Core Team and recorded in Git history.
|
||||
|
||||
---
|
||||
|
||||
_The Bootstrap maintainers are committed to transparency, user trust, and continuous improvement in our security and response practices._
|
||||
@@ -22,12 +22,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
name: Build CSS
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'scss/**'
|
||||
- 'build/**'
|
||||
- 'package.json'
|
||||
- 'package-lock.json'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 2
|
||||
NODE: 22
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-css:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build CSS
|
||||
run: npm run css
|
||||
|
||||
- name: Upload CSS artifacts
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: css-dist
|
||||
path: dist/css/
|
||||
retention-days: 1
|
||||
@@ -0,0 +1,46 @@
|
||||
name: Build JS
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'js/**'
|
||||
- 'build/**'
|
||||
- 'package.json'
|
||||
- 'package-lock.json'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 2
|
||||
NODE: 22
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-js:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build JS
|
||||
run: npm run js
|
||||
|
||||
- name: Upload JS artifacts
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: js-dist
|
||||
path: dist/js/
|
||||
retention-days: 1
|
||||
@@ -15,17 +15,17 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
bundlewatch:
|
||||
build-dist:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
@@ -33,8 +33,58 @@ jobs:
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run dist
|
||||
run: npm run dist
|
||||
- name: Build CSS
|
||||
run: npm run css
|
||||
|
||||
- name: Build JS
|
||||
run: npm run js
|
||||
|
||||
- name: Upload CSS artifacts
|
||||
id: css-artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: css-dist
|
||||
path: dist/css/
|
||||
retention-days: 1
|
||||
|
||||
- name: Upload JS artifacts
|
||||
id: js-artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: js-dist
|
||||
path: dist/js/
|
||||
retention-days: 1
|
||||
|
||||
bundlewatch:
|
||||
needs: build-dist
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Download CSS artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: css-dist
|
||||
path: dist/css/
|
||||
|
||||
- name: Download JS artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: js-dist
|
||||
path: dist/js/
|
||||
|
||||
- name: Run bundlewatch
|
||||
run: npm run bundlewatch
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
name: CDN Distribution
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 2
|
||||
NODE: 22
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-cdn:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'twbs/bootstrap' && startsWith(github.event.release.tag_name, 'v') }}
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build CSS
|
||||
run: npm run css
|
||||
|
||||
- name: Build JS
|
||||
run: npm run js
|
||||
|
||||
- name: Generate SRI hashes
|
||||
run: npm run release-sri
|
||||
|
||||
- name: Upload to CDN
|
||||
# This would typically upload to a CDN service like jsDelivr, unpkg, etc.
|
||||
# The actual implementation would depend on the CDN service used
|
||||
run: |
|
||||
echo "CDN upload would happen here"
|
||||
echo "Files ready for CDN distribution:"
|
||||
ls -la dist/css/
|
||||
ls -la dist/js/
|
||||
@@ -24,21 +24,21 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||
uses: github/codeql-action/init@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
|
||||
with:
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
languages: "javascript"
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||
uses: github/codeql-action/autobuild@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||
uses: github/codeql-action/analyze@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
|
||||
with:
|
||||
category: "/language:javascript"
|
||||
|
||||
@@ -23,12 +23,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Run cspell
|
||||
uses: streetsidesoftware/cspell-action@e5a858a18b7e0b56e0342b1dcad796308b7341a2 # v8.1.1
|
||||
uses: streetsidesoftware/cspell-action@dcd03dc3e8a59ec2e360d0c62db517baa0b4bb6d # v7.2.0
|
||||
with:
|
||||
config: ".cspell.json"
|
||||
files: "**/*.{md,mdx}"
|
||||
|
||||
@@ -15,17 +15,17 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
css:
|
||||
build-css:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
@@ -36,5 +36,38 @@ jobs:
|
||||
- name: Build CSS
|
||||
run: npm run css
|
||||
|
||||
- name: Upload CSS artifacts
|
||||
id: css-artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: css-dist
|
||||
path: dist/css/
|
||||
retention-days: 1
|
||||
|
||||
css:
|
||||
needs: build-css
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Download CSS artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: css-dist
|
||||
path: dist/css/
|
||||
|
||||
- name: Run CSS tests
|
||||
run: npm run css-test
|
||||
|
||||
@@ -15,34 +15,85 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
docs:
|
||||
build-dist:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
- run: java -version
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build CSS
|
||||
run: npm run css
|
||||
|
||||
- name: Build JS
|
||||
run: npm run js
|
||||
|
||||
- name: Upload CSS artifacts
|
||||
id: css-artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: css-dist
|
||||
path: dist/css/
|
||||
retention-days: 1
|
||||
|
||||
- name: Upload JS artifacts
|
||||
id: js-artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: js-dist
|
||||
path: dist/js/
|
||||
retention-days: 1
|
||||
|
||||
docs:
|
||||
needs: build-dist
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Download CSS artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: css-dist
|
||||
path: dist/css/
|
||||
|
||||
- name: Download JS artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: js-dist
|
||||
path: dist/js/
|
||||
|
||||
- name: Build docs
|
||||
run: npm run docs-build
|
||||
|
||||
- name: Validate HTML
|
||||
run: npm run docs-vnu
|
||||
run: npm run docs-html-validate
|
||||
|
||||
- name: Run linkinator
|
||||
uses: JustinBeckwith/linkinator-action@af984b9f30f63e796ae2ea5be5e07cb587f1bbd9 # v2.3
|
||||
uses: JustinBeckwith/linkinator-action@3d5ba091319fa7b0ac14703761eebb7d100e6f6d # v1.11.0
|
||||
with:
|
||||
paths: _site
|
||||
recurse: true
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
if: github.repository == 'twbs/bootstrap'
|
||||
steps:
|
||||
- name: awaiting reply
|
||||
uses: actions-cool/issues-helper@d1d51fccf39469b5458203b1369060db0ff0c0db # v3.7.4
|
||||
uses: actions-cool/issues-helper@45d75b6cf72bf4f254be6230cb887ad002702491 # v3.6.3
|
||||
with:
|
||||
actions: "close-issues"
|
||||
labels: "awaiting-reply"
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
steps:
|
||||
- name: awaiting reply
|
||||
if: github.event.label.name == 'needs-example'
|
||||
uses: actions-cool/issues-helper@d1d51fccf39469b5458203b1369060db0ff0c0db # v3.7.4
|
||||
uses: actions-cool/issues-helper@45d75b6cf72bf4f254be6230cb887ad002702491 # v3.6.3
|
||||
with:
|
||||
actions: "create-comment"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -15,7 +15,37 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-js:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: ${{ env.NODE }}
|
||||
cache: npm
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build JS
|
||||
run: npm run js
|
||||
|
||||
- name: Upload JS artifacts
|
||||
id: js-artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: js-dist
|
||||
path: dist/js/
|
||||
retention-days: 1
|
||||
|
||||
run:
|
||||
needs: build-js
|
||||
permissions:
|
||||
# allow coverallsapp/github-action to create new checks issues and fetch code
|
||||
checks: write
|
||||
@@ -25,12 +55,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: ${{ env.NODE }}
|
||||
cache: npm
|
||||
@@ -38,14 +68,17 @@ jobs:
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run dist
|
||||
run: npm run js
|
||||
- name: Download JS artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: js-dist
|
||||
path: dist/js/
|
||||
|
||||
- name: Run JS tests
|
||||
run: npm run js-test
|
||||
|
||||
- name: Run Coveralls
|
||||
uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2.3.7
|
||||
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6
|
||||
if: ${{ !github.event.repository.fork }}
|
||||
with:
|
||||
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
@@ -20,12 +20,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
name: CSS (node-sass)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 2
|
||||
NODE: 22
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
css:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
|
||||
- name: Build CSS with node-sass
|
||||
run: |
|
||||
npx --package node-sass@latest node-sass --version
|
||||
npx --package node-sass@latest node-sass --output-style expanded --source-map true --source-map-contents true --precision 6 scss/ -o dist-sass/css/
|
||||
ls -Al dist-sass/css
|
||||
|
||||
- name: Check built CSS files for Sass variables
|
||||
shell: bash
|
||||
run: |
|
||||
SASS_VARS_FOUND=$(find "dist-sass/css/" -type f -name "*.css" -print0 | xargs -0 --no-run-if-empty grep -F "\$" || true)
|
||||
if [[ -z "$SASS_VARS_FOUND" ]]; then
|
||||
echo "All good, no Sass variables found!"
|
||||
exit 0
|
||||
else
|
||||
echo "Found $(echo "$SASS_VARS_FOUND" | wc -l | bc) Sass variables:"
|
||||
echo "$SASS_VARS_FOUND"
|
||||
exit 1
|
||||
fi
|
||||
@@ -13,11 +13,28 @@ jobs:
|
||||
if: ${{ github.repository == 'twbs/bootstrap' && startsWith(github.event.release.tag_name, 'v') }}
|
||||
env:
|
||||
GITHUB_REF_NAME: ${{ github.ref_name }}
|
||||
FORCE_COLOR: 2
|
||||
NODE: 22
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build CSS
|
||||
run: npm run css
|
||||
|
||||
- name: Build JS
|
||||
run: npm run js
|
||||
|
||||
- name: Set up NuGet
|
||||
uses: nuget/setup-nuget@323ab0502cd38fdc493335025a96c8fdb0edc71f # v2.0.1
|
||||
with:
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 2
|
||||
NODE: 22
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build-and-release:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'twbs/bootstrap' && (github.event_name == 'release' || github.event_name == 'workflow_dispatch') }}
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build CSS
|
||||
run: npm run css
|
||||
|
||||
- name: Build JS
|
||||
run: npm run js
|
||||
|
||||
- name: Generate SRI hashes
|
||||
run: npm run release-sri
|
||||
|
||||
- name: Build docs
|
||||
run: npm run docs-build
|
||||
|
||||
- name: Create release zip
|
||||
run: npm run release-zip
|
||||
|
||||
- name: Create examples zip
|
||||
run: npm run release-zip-examples
|
||||
|
||||
- name: Upload dist files to release
|
||||
uses: actions/upload-release-asset@v1
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ github.event.release.upload_url }}
|
||||
asset_path: ./bootstrap-${{ github.event.release.tag_name }}-dist.zip
|
||||
asset_name: bootstrap-${{ github.event.release.tag_name }}-dist.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Upload examples to release
|
||||
uses: actions/upload-release-asset@v1
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ github.event.release.upload_url }}
|
||||
asset_path: ./bootstrap-${{ github.event.release.tag_name }}-examples.zip
|
||||
asset_name: bootstrap-${{ github.event.release.tag_name }}-examples.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Commit dist files for npm
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git add dist/
|
||||
git commit -m "Add dist files for release ${{ github.event.release.tag_name }}" || exit 0
|
||||
git push
|
||||
|
||||
- name: Publish to npm
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
run: npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
@@ -34,12 +34,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
|
||||
uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
@@ -73,6 +73,6 @@ jobs:
|
||||
# Upload the results to GitHub's code scanning dashboard (optional).
|
||||
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||
uses: github/codeql-action/upload-sarif@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -34,6 +34,7 @@ Thumbs.db
|
||||
*.komodoproject
|
||||
|
||||
# Folders to ignore
|
||||
/dist/
|
||||
/dist-sass/
|
||||
/js/coverage/
|
||||
/node_modules/
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"default": true,
|
||||
"MD004": { "style": "dash" },
|
||||
"MD011": false,
|
||||
"MD013": false,
|
||||
"MD024": false,
|
||||
"MD025": false,
|
||||
"MD026": false,
|
||||
"MD031": false,
|
||||
"MD033": false,
|
||||
"MD034": false,
|
||||
"MD037": false,
|
||||
"MD038": false,
|
||||
"MD041": false,
|
||||
"MD046": false,
|
||||
"line-length": false,
|
||||
"no-inline-html": false
|
||||
}
|
||||
@@ -13,7 +13,6 @@
|
||||
"outline": "none"
|
||||
},
|
||||
"function-disallowed-list": [
|
||||
"calc",
|
||||
"lighten",
|
||||
"darken"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/*!
|
||||
* Script to run html-validate for HTML validation.
|
||||
*
|
||||
* This replaces the Java-based vnu-jar validator with a faster, Node.js-only solution.
|
||||
* Benefits:
|
||||
* - No Java dependency required
|
||||
* - Faster execution (no JVM startup time)
|
||||
* - Easy to configure with rule-based system
|
||||
* - Better integration with Node.js build tools
|
||||
*
|
||||
* Copyright 2017-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
||||
import { HtmlValidate } from 'html-validate'
|
||||
import { globby } from 'globby'
|
||||
|
||||
const htmlValidate = new HtmlValidate({
|
||||
rules: {
|
||||
// Allow autocomplete on buttons (Bootstrap specific)
|
||||
'attribute-allowed-values': 'off',
|
||||
// Allow aria-disabled on links (Bootstrap specific)
|
||||
'aria-label-misuse': 'off',
|
||||
// Allow modern CSS syntax
|
||||
'valid-id': 'off',
|
||||
// Allow void elements with trailing slashes (Astro)
|
||||
'void-style': 'off',
|
||||
// Allow custom attributes
|
||||
'no-unknown-elements': 'off',
|
||||
'attribute-boolean-style': 'off',
|
||||
'no-inline-style': 'off',
|
||||
// KEEP duplicate ID checking enabled (this is important for HTML validity)
|
||||
'no-dup-id': 'error'
|
||||
},
|
||||
elements: [
|
||||
'html5',
|
||||
{
|
||||
// Allow custom attributes for Astro/framework compatibility
|
||||
'*': {
|
||||
attributes: {
|
||||
'is:raw': { boolean: true },
|
||||
switch: { boolean: true },
|
||||
autocomplete: { enum: ['on', 'off', 'new-password', 'current-password'] }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
async function validateHTML() {
|
||||
try {
|
||||
console.log('Running html-validate validation...')
|
||||
|
||||
// Find all HTML files
|
||||
const files = await globby([
|
||||
'_site/**/*.html',
|
||||
'js/tests/**/*.html'
|
||||
], {
|
||||
ignore: ['**/node_modules/**']
|
||||
})
|
||||
|
||||
console.log(`Validating ${files.length} HTML files...`)
|
||||
|
||||
let hasErrors = false
|
||||
|
||||
// Validate all files in parallel to avoid await-in-loop
|
||||
const validationPromises = files.map(file =>
|
||||
htmlValidate.validateFile(file).then(report => ({ file, report }))
|
||||
)
|
||||
|
||||
const validationResults = await Promise.all(validationPromises)
|
||||
|
||||
// Process results and check for errors
|
||||
for (const { file, report } of validationResults) {
|
||||
if (!report.valid) {
|
||||
hasErrors = true
|
||||
console.error(`\nErrors in ${file}:`)
|
||||
|
||||
// Extract error messages with reduced nesting
|
||||
const errorMessages = report.results.flatMap(result =>
|
||||
result.messages.filter(message => message.severity === 2)
|
||||
)
|
||||
|
||||
for (const message of errorMessages) {
|
||||
console.error(` Line ${message.line}:${message.column} - ${message.message} (${message.ruleId})`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasErrors) {
|
||||
console.error('\nHTML validation failed!')
|
||||
process.exit(1)
|
||||
} else {
|
||||
console.log('✓ All HTML files are valid!')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('HTML validation error:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
validateHTML()
|
||||
@@ -1,66 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/*!
|
||||
* Script to run vnu-jar if Java is available.
|
||||
* Copyright 2017-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
||||
import { execFile, spawn } from 'node:child_process'
|
||||
import vnu from 'vnu-jar'
|
||||
|
||||
execFile('java', ['-version'], (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error('Skipping vnu-jar test; Java is probably missing.')
|
||||
console.error(error)
|
||||
return
|
||||
}
|
||||
|
||||
console.log('Running vnu-jar validation...')
|
||||
|
||||
const is32bitJava = !/64-Bit/.test(stderr)
|
||||
|
||||
// vnu-jar accepts multiple ignores joined with a `|`.
|
||||
// Also note that the ignores are string regular expressions.
|
||||
const ignores = [
|
||||
// "autocomplete" is included in <button> and checkboxes and radio <input>s due to
|
||||
// Firefox's non-standard autocomplete behavior - see https://bugzilla.mozilla.org/show_bug.cgi?id=654072
|
||||
'Attribute “autocomplete” is only allowed when the input type is.*',
|
||||
'Attribute “autocomplete” not allowed on element “button” at this point.',
|
||||
// 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 <br />
|
||||
'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.'
|
||||
].join('|')
|
||||
|
||||
const args = [
|
||||
'-jar',
|
||||
`"${vnu}"`,
|
||||
'--asciiquotes',
|
||||
'--skip-non-html',
|
||||
'--Werror',
|
||||
`--filterpattern "${ignores}"`,
|
||||
'_site/',
|
||||
'js/tests/'
|
||||
]
|
||||
|
||||
// For the 32-bit Java we need to pass `-Xss512k`
|
||||
if (is32bitJava) {
|
||||
args.splice(0, 0, '-Xss512k')
|
||||
}
|
||||
|
||||
console.log(`command used: java ${args.join(' ')}`)
|
||||
|
||||
return spawn('java', args, {
|
||||
shell: true,
|
||||
stdio: 'inherit'
|
||||
})
|
||||
.on('exit', process.exit)
|
||||
})
|
||||
Vendored
+206
-511
@@ -57,252 +57,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/index.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const MAX_UID = 1000000;
|
||||
const MILLISECONDS_MULTIPLIER = 1000;
|
||||
const TRANSITION_END = 'transitionend';
|
||||
|
||||
/**
|
||||
* Properly escape IDs selectors to handle weird IDs
|
||||
* @param {string} selector
|
||||
* @returns {string}
|
||||
*/
|
||||
const parseSelector = selector => {
|
||||
if (selector && window.CSS && window.CSS.escape) {
|
||||
// document.querySelector needs escaping to handle IDs (html5+) containing for instance /
|
||||
selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`);
|
||||
}
|
||||
return selector;
|
||||
};
|
||||
|
||||
// Shout-out Angus Croll (https://goo.gl/pxwQGp)
|
||||
const toType = object => {
|
||||
if (object === null || object === undefined) {
|
||||
return `${object}`;
|
||||
}
|
||||
return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Public Util API
|
||||
*/
|
||||
|
||||
const getUID = prefix => {
|
||||
do {
|
||||
prefix += Math.floor(Math.random() * MAX_UID);
|
||||
} while (document.getElementById(prefix));
|
||||
return prefix;
|
||||
};
|
||||
const getTransitionDurationFromElement = element => {
|
||||
if (!element) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get transition-duration of the element
|
||||
let {
|
||||
transitionDuration,
|
||||
transitionDelay
|
||||
} = window.getComputedStyle(element);
|
||||
const floatTransitionDuration = Number.parseFloat(transitionDuration);
|
||||
const floatTransitionDelay = Number.parseFloat(transitionDelay);
|
||||
|
||||
// Return 0 if element or transition duration is not found
|
||||
if (!floatTransitionDuration && !floatTransitionDelay) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If multiple durations are defined, take the first
|
||||
transitionDuration = transitionDuration.split(',')[0];
|
||||
transitionDelay = transitionDelay.split(',')[0];
|
||||
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
|
||||
};
|
||||
const triggerTransitionEnd = element => {
|
||||
element.dispatchEvent(new Event(TRANSITION_END));
|
||||
};
|
||||
const isElement$1 = object => {
|
||||
if (!object || typeof object !== 'object') {
|
||||
return false;
|
||||
}
|
||||
if (typeof object.jquery !== 'undefined') {
|
||||
object = object[0];
|
||||
}
|
||||
return typeof object.nodeType !== 'undefined';
|
||||
};
|
||||
const getElement = object => {
|
||||
// it's a jQuery object or a node element
|
||||
if (isElement$1(object)) {
|
||||
return object.jquery ? object[0] : object;
|
||||
}
|
||||
if (typeof object === 'string' && object.length > 0) {
|
||||
return document.querySelector(parseSelector(object));
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const isVisible = element => {
|
||||
if (!isElement$1(element) || element.getClientRects().length === 0) {
|
||||
return false;
|
||||
}
|
||||
const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
||||
// Handle `details` element as its content may falsie appear visible when it is closed
|
||||
const closedDetails = element.closest('details:not([open])');
|
||||
if (!closedDetails) {
|
||||
return elementIsVisible;
|
||||
}
|
||||
if (closedDetails !== element) {
|
||||
const summary = element.closest('summary');
|
||||
if (summary && summary.parentNode !== closedDetails) {
|
||||
return false;
|
||||
}
|
||||
if (summary === null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return elementIsVisible;
|
||||
};
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
const findShadowRoot = element => {
|
||||
if (!document.documentElement.attachShadow) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Can find the shadow root otherwise it'll return the document
|
||||
if (typeof element.getRootNode === 'function') {
|
||||
const root = element.getRootNode();
|
||||
return root instanceof ShadowRoot ? root : null;
|
||||
}
|
||||
if (element instanceof ShadowRoot) {
|
||||
return element;
|
||||
}
|
||||
|
||||
// when we don't find a shadow root
|
||||
if (!element.parentNode) {
|
||||
return null;
|
||||
}
|
||||
return findShadowRoot(element.parentNode);
|
||||
};
|
||||
const noop = () => {};
|
||||
|
||||
/**
|
||||
* Trick to restart an element's animation
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @return void
|
||||
*
|
||||
* @see https://www.harrytheo.com/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||||
*/
|
||||
const reflow = element => {
|
||||
element.offsetHeight; // eslint-disable-line no-unused-expressions
|
||||
};
|
||||
const getjQuery = () => {
|
||||
if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return window.jQuery;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
for (const callback of DOMContentLoadedCallbacks) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
const isRTL = () => document.documentElement.dir === 'rtl';
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
|
||||
return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue;
|
||||
};
|
||||
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
|
||||
if (!waitForTransition) {
|
||||
execute(callback);
|
||||
return;
|
||||
}
|
||||
const durationPadding = 5;
|
||||
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
||||
let called = false;
|
||||
const handler = ({
|
||||
target
|
||||
}) => {
|
||||
if (target !== transitionElement) {
|
||||
return;
|
||||
}
|
||||
called = true;
|
||||
transitionElement.removeEventListener(TRANSITION_END, handler);
|
||||
execute(callback);
|
||||
};
|
||||
transitionElement.addEventListener(TRANSITION_END, handler);
|
||||
setTimeout(() => {
|
||||
if (!called) {
|
||||
triggerTransitionEnd(transitionElement);
|
||||
}
|
||||
}, emulatedDuration);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the previous/next element of a list.
|
||||
*
|
||||
* @param {array} list The list of elements
|
||||
* @param activeElement The active element
|
||||
* @param shouldGetNext Choose to get next or previous element
|
||||
* @param isCycleAllowed
|
||||
* @return {Element|elem} The proper element
|
||||
*/
|
||||
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
|
||||
const listLength = list.length;
|
||||
let index = list.indexOf(activeElement);
|
||||
|
||||
// if the element does not exist in the list return an element
|
||||
// depending on the direction and if cycle is allowed
|
||||
if (index === -1) {
|
||||
return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];
|
||||
}
|
||||
index += shouldGetNext ? 1 : -1;
|
||||
if (isCycleAllowed) {
|
||||
index = (index + listLength) % listLength;
|
||||
}
|
||||
return list[Math.max(0, Math.min(index, listLength - 1))];
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap dom/event-handler.js
|
||||
@@ -310,7 +64,6 @@
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
@@ -479,33 +232,11 @@
|
||||
if (typeof event !== 'string' || !element) {
|
||||
return null;
|
||||
}
|
||||
const $ = getjQuery();
|
||||
const typeEvent = getTypeEvent(event);
|
||||
const inNamespace = event !== typeEvent;
|
||||
let jQueryEvent = null;
|
||||
let bubbles = true;
|
||||
let nativeDispatch = true;
|
||||
let defaultPrevented = false;
|
||||
if (inNamespace && $) {
|
||||
jQueryEvent = $.Event(event, args);
|
||||
$(element).trigger(jQueryEvent);
|
||||
bubbles = !jQueryEvent.isPropagationStopped();
|
||||
nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
|
||||
defaultPrevented = jQueryEvent.isDefaultPrevented();
|
||||
}
|
||||
const evt = hydrateObj(new Event(event, {
|
||||
bubbles,
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
}), args);
|
||||
if (defaultPrevented) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
if (nativeDispatch) {
|
||||
element.dispatchEvent(evt);
|
||||
}
|
||||
if (evt.defaultPrevented && jQueryEvent) {
|
||||
jQueryEvent.preventDefault();
|
||||
}
|
||||
element.dispatchEvent(evt);
|
||||
return evt;
|
||||
}
|
||||
};
|
||||
@@ -582,6 +313,210 @@
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/index.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const MAX_UID = 1000000;
|
||||
const MILLISECONDS_MULTIPLIER = 1000;
|
||||
const TRANSITION_END = 'transitionend';
|
||||
|
||||
/**
|
||||
* Properly escape IDs selectors to handle weird IDs
|
||||
* @param {string} selector
|
||||
* @returns {string}
|
||||
*/
|
||||
const parseSelector = selector => {
|
||||
if (selector && window.CSS && window.CSS.escape) {
|
||||
// document.querySelector needs escaping to handle IDs (html5+) containing for instance /
|
||||
selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`);
|
||||
}
|
||||
return selector;
|
||||
};
|
||||
|
||||
// Shout-out Angus Croll (https://goo.gl/pxwQGp)
|
||||
const toType = object => {
|
||||
if (object === null || object === undefined) {
|
||||
return `${object}`;
|
||||
}
|
||||
return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Public Util API
|
||||
*/
|
||||
|
||||
const getUID = prefix => {
|
||||
do {
|
||||
prefix += Math.floor(Math.random() * MAX_UID);
|
||||
} while (document.getElementById(prefix));
|
||||
return prefix;
|
||||
};
|
||||
const getTransitionDurationFromElement = element => {
|
||||
if (!element) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get transition-duration of the element
|
||||
let {
|
||||
transitionDuration,
|
||||
transitionDelay
|
||||
} = window.getComputedStyle(element);
|
||||
const floatTransitionDuration = Number.parseFloat(transitionDuration);
|
||||
const floatTransitionDelay = Number.parseFloat(transitionDelay);
|
||||
|
||||
// Return 0 if element or transition duration is not found
|
||||
if (!floatTransitionDuration && !floatTransitionDelay) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If multiple durations are defined, take the first
|
||||
transitionDuration = transitionDuration.split(',')[0];
|
||||
transitionDelay = transitionDelay.split(',')[0];
|
||||
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
|
||||
};
|
||||
const triggerTransitionEnd = element => {
|
||||
element.dispatchEvent(new Event(TRANSITION_END));
|
||||
};
|
||||
const isElement$1 = object => {
|
||||
if (!object || typeof object !== 'object') {
|
||||
return false;
|
||||
}
|
||||
return typeof object.nodeType !== 'undefined';
|
||||
};
|
||||
const getElement = object => {
|
||||
if (isElement$1(object)) {
|
||||
return object;
|
||||
}
|
||||
if (typeof object === 'string' && object.length > 0) {
|
||||
return document.querySelector(parseSelector(object));
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const isVisible = element => {
|
||||
if (!isElement$1(element) || element.getClientRects().length === 0) {
|
||||
return false;
|
||||
}
|
||||
const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
||||
// Handle `details` element as its content may falsie appear visible when it is closed
|
||||
const closedDetails = element.closest('details:not([open])');
|
||||
if (!closedDetails) {
|
||||
return elementIsVisible;
|
||||
}
|
||||
if (closedDetails !== element) {
|
||||
const summary = element.closest('summary');
|
||||
if (summary && summary.parentNode !== closedDetails) {
|
||||
return false;
|
||||
}
|
||||
if (summary === null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return elementIsVisible;
|
||||
};
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
const findShadowRoot = element => {
|
||||
if (!document.documentElement.attachShadow) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Can find the shadow root otherwise it'll return the document
|
||||
if (typeof element.getRootNode === 'function') {
|
||||
const root = element.getRootNode();
|
||||
return root instanceof ShadowRoot ? root : null;
|
||||
}
|
||||
if (element instanceof ShadowRoot) {
|
||||
return element;
|
||||
}
|
||||
|
||||
// when we don't find a shadow root
|
||||
if (!element.parentNode) {
|
||||
return null;
|
||||
}
|
||||
return findShadowRoot(element.parentNode);
|
||||
};
|
||||
const noop = () => {};
|
||||
|
||||
/**
|
||||
* Trick to restart an element's animation
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @return void
|
||||
*
|
||||
* @see https://www.harrytheo.com/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||||
*/
|
||||
const reflow = element => {
|
||||
element.offsetHeight; // eslint-disable-line no-unused-expressions
|
||||
};
|
||||
const isRTL = () => document.documentElement.dir === 'rtl';
|
||||
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
|
||||
return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue;
|
||||
};
|
||||
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
|
||||
if (!waitForTransition) {
|
||||
execute(callback);
|
||||
return;
|
||||
}
|
||||
const durationPadding = 5;
|
||||
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
||||
let called = false;
|
||||
const handler = ({
|
||||
target
|
||||
}) => {
|
||||
if (target !== transitionElement) {
|
||||
return;
|
||||
}
|
||||
called = true;
|
||||
transitionElement.removeEventListener(TRANSITION_END, handler);
|
||||
execute(callback);
|
||||
};
|
||||
transitionElement.addEventListener(TRANSITION_END, handler);
|
||||
setTimeout(() => {
|
||||
if (!called) {
|
||||
triggerTransitionEnd(transitionElement);
|
||||
}
|
||||
}, emulatedDuration);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the previous/next element of a list.
|
||||
*
|
||||
* @param {array} list The list of elements
|
||||
* @param activeElement The active element
|
||||
* @param shouldGetNext Choose to get next or previous element
|
||||
* @param isCycleAllowed
|
||||
* @return {Element|elem} The proper element
|
||||
*/
|
||||
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
|
||||
const listLength = list.length;
|
||||
let index = list.indexOf(activeElement);
|
||||
|
||||
// if the element does not exist in the list return an element
|
||||
// depending on the direction and if cycle is allowed
|
||||
if (index === -1) {
|
||||
return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];
|
||||
}
|
||||
index += shouldGetNext ? 1 : -1;
|
||||
if (isCycleAllowed) {
|
||||
index = (index + listLength) % listLength;
|
||||
}
|
||||
return list[Math.max(0, Math.min(index, listLength - 1))];
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/config.js
|
||||
@@ -867,20 +802,6 @@
|
||||
EventHandler.trigger(this._element, EVENT_CLOSED);
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Alert.getOrCreateInstance(this);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -889,12 +810,6 @@
|
||||
|
||||
enableDismissTrigger(Alert, 'close');
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Alert);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap button.js
|
||||
@@ -930,16 +845,6 @@
|
||||
// Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
|
||||
this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Button.getOrCreateInstance(this);
|
||||
if (config === 'toggle') {
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -953,12 +858,6 @@
|
||||
data.toggle();
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Button);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/swipe.js
|
||||
@@ -1395,23 +1294,6 @@
|
||||
}
|
||||
return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Carousel.getOrCreateInstance(this, config);
|
||||
if (typeof config === 'number') {
|
||||
data.to(config);
|
||||
return;
|
||||
}
|
||||
if (typeof config === 'string') {
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1446,12 +1328,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Carousel);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap collapse.js
|
||||
@@ -1645,23 +1521,6 @@
|
||||
element.setAttribute('aria-expanded', isOpen);
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
const _config = {};
|
||||
if (typeof config === 'string' && /show|hide/.test(config)) {
|
||||
_config.toggle = false;
|
||||
}
|
||||
return this.each(function () {
|
||||
const data = Collapse.getOrCreateInstance(this, _config);
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1680,12 +1539,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Collapse);
|
||||
|
||||
var top = 'top';
|
||||
var bottom = 'bottom';
|
||||
var right = 'right';
|
||||
@@ -3796,20 +3649,6 @@
|
||||
// allow cycling to get the last item in case key equals ARROW_UP_KEY
|
||||
getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus();
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Dropdown.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
static clearMenus(event) {
|
||||
if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) {
|
||||
return;
|
||||
@@ -3885,12 +3724,6 @@
|
||||
Dropdown.getOrCreateInstance(this).toggle();
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Dropdown);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/backdrop.js
|
||||
@@ -4463,20 +4296,6 @@
|
||||
this._element.style.paddingLeft = '';
|
||||
this._element.style.paddingRight = '';
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config, relatedTarget) {
|
||||
return this.each(function () {
|
||||
const data = Modal.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](relatedTarget);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4510,12 +4329,6 @@
|
||||
});
|
||||
enableDismissTrigger(Modal);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Modal);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap offcanvas.js
|
||||
@@ -4684,20 +4497,6 @@
|
||||
EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
|
||||
});
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Offcanvas.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4741,12 +4540,6 @@
|
||||
});
|
||||
enableDismissTrigger(Offcanvas);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Offcanvas);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/sanitizer.js
|
||||
@@ -5468,28 +5261,8 @@
|
||||
this.tip = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Tooltip.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Tooltip);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap popover.js
|
||||
@@ -5549,28 +5322,8 @@
|
||||
_getContent() {
|
||||
return this._resolvePossibleFunction(this._config.content);
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Popover.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Popover);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap scrollspy.js
|
||||
@@ -5799,20 +5552,6 @@
|
||||
node.classList.remove(CLASS_NAME_ACTIVE$1);
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = ScrollSpy.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5825,12 +5564,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(ScrollSpy);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap tab.js
|
||||
@@ -6057,20 +5790,6 @@
|
||||
_getOuterElement(elem) {
|
||||
return elem.closest(SELECTOR_OUTER) || elem;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Tab.getOrCreateInstance(this);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6095,11 +5814,6 @@
|
||||
Tab.getOrCreateInstance(element);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Tab);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
@@ -6257,19 +5971,6 @@
|
||||
clearTimeout(this._timeout);
|
||||
this._timeout = null;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Toast.getOrCreateInstance(this, config);
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6278,12 +5979,6 @@
|
||||
|
||||
enableDismissTrigger(Toast);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Toast);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap index.umd.js
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+206
-511
@@ -53,252 +53,6 @@ const Data = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/index.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const MAX_UID = 1000000;
|
||||
const MILLISECONDS_MULTIPLIER = 1000;
|
||||
const TRANSITION_END = 'transitionend';
|
||||
|
||||
/**
|
||||
* Properly escape IDs selectors to handle weird IDs
|
||||
* @param {string} selector
|
||||
* @returns {string}
|
||||
*/
|
||||
const parseSelector = selector => {
|
||||
if (selector && window.CSS && window.CSS.escape) {
|
||||
// document.querySelector needs escaping to handle IDs (html5+) containing for instance /
|
||||
selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`);
|
||||
}
|
||||
return selector;
|
||||
};
|
||||
|
||||
// Shout-out Angus Croll (https://goo.gl/pxwQGp)
|
||||
const toType = object => {
|
||||
if (object === null || object === undefined) {
|
||||
return `${object}`;
|
||||
}
|
||||
return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Public Util API
|
||||
*/
|
||||
|
||||
const getUID = prefix => {
|
||||
do {
|
||||
prefix += Math.floor(Math.random() * MAX_UID);
|
||||
} while (document.getElementById(prefix));
|
||||
return prefix;
|
||||
};
|
||||
const getTransitionDurationFromElement = element => {
|
||||
if (!element) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get transition-duration of the element
|
||||
let {
|
||||
transitionDuration,
|
||||
transitionDelay
|
||||
} = window.getComputedStyle(element);
|
||||
const floatTransitionDuration = Number.parseFloat(transitionDuration);
|
||||
const floatTransitionDelay = Number.parseFloat(transitionDelay);
|
||||
|
||||
// Return 0 if element or transition duration is not found
|
||||
if (!floatTransitionDuration && !floatTransitionDelay) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If multiple durations are defined, take the first
|
||||
transitionDuration = transitionDuration.split(',')[0];
|
||||
transitionDelay = transitionDelay.split(',')[0];
|
||||
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
|
||||
};
|
||||
const triggerTransitionEnd = element => {
|
||||
element.dispatchEvent(new Event(TRANSITION_END));
|
||||
};
|
||||
const isElement = object => {
|
||||
if (!object || typeof object !== 'object') {
|
||||
return false;
|
||||
}
|
||||
if (typeof object.jquery !== 'undefined') {
|
||||
object = object[0];
|
||||
}
|
||||
return typeof object.nodeType !== 'undefined';
|
||||
};
|
||||
const getElement = object => {
|
||||
// it's a jQuery object or a node element
|
||||
if (isElement(object)) {
|
||||
return object.jquery ? object[0] : object;
|
||||
}
|
||||
if (typeof object === 'string' && object.length > 0) {
|
||||
return document.querySelector(parseSelector(object));
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const isVisible = element => {
|
||||
if (!isElement(element) || element.getClientRects().length === 0) {
|
||||
return false;
|
||||
}
|
||||
const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
||||
// Handle `details` element as its content may falsie appear visible when it is closed
|
||||
const closedDetails = element.closest('details:not([open])');
|
||||
if (!closedDetails) {
|
||||
return elementIsVisible;
|
||||
}
|
||||
if (closedDetails !== element) {
|
||||
const summary = element.closest('summary');
|
||||
if (summary && summary.parentNode !== closedDetails) {
|
||||
return false;
|
||||
}
|
||||
if (summary === null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return elementIsVisible;
|
||||
};
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
const findShadowRoot = element => {
|
||||
if (!document.documentElement.attachShadow) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Can find the shadow root otherwise it'll return the document
|
||||
if (typeof element.getRootNode === 'function') {
|
||||
const root = element.getRootNode();
|
||||
return root instanceof ShadowRoot ? root : null;
|
||||
}
|
||||
if (element instanceof ShadowRoot) {
|
||||
return element;
|
||||
}
|
||||
|
||||
// when we don't find a shadow root
|
||||
if (!element.parentNode) {
|
||||
return null;
|
||||
}
|
||||
return findShadowRoot(element.parentNode);
|
||||
};
|
||||
const noop = () => {};
|
||||
|
||||
/**
|
||||
* Trick to restart an element's animation
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @return void
|
||||
*
|
||||
* @see https://www.harrytheo.com/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||||
*/
|
||||
const reflow = element => {
|
||||
element.offsetHeight; // eslint-disable-line no-unused-expressions
|
||||
};
|
||||
const getjQuery = () => {
|
||||
if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return window.jQuery;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
for (const callback of DOMContentLoadedCallbacks) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
const isRTL = () => document.documentElement.dir === 'rtl';
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
|
||||
return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue;
|
||||
};
|
||||
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
|
||||
if (!waitForTransition) {
|
||||
execute(callback);
|
||||
return;
|
||||
}
|
||||
const durationPadding = 5;
|
||||
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
||||
let called = false;
|
||||
const handler = ({
|
||||
target
|
||||
}) => {
|
||||
if (target !== transitionElement) {
|
||||
return;
|
||||
}
|
||||
called = true;
|
||||
transitionElement.removeEventListener(TRANSITION_END, handler);
|
||||
execute(callback);
|
||||
};
|
||||
transitionElement.addEventListener(TRANSITION_END, handler);
|
||||
setTimeout(() => {
|
||||
if (!called) {
|
||||
triggerTransitionEnd(transitionElement);
|
||||
}
|
||||
}, emulatedDuration);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the previous/next element of a list.
|
||||
*
|
||||
* @param {array} list The list of elements
|
||||
* @param activeElement The active element
|
||||
* @param shouldGetNext Choose to get next or previous element
|
||||
* @param isCycleAllowed
|
||||
* @return {Element|elem} The proper element
|
||||
*/
|
||||
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
|
||||
const listLength = list.length;
|
||||
let index = list.indexOf(activeElement);
|
||||
|
||||
// if the element does not exist in the list return an element
|
||||
// depending on the direction and if cycle is allowed
|
||||
if (index === -1) {
|
||||
return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];
|
||||
}
|
||||
index += shouldGetNext ? 1 : -1;
|
||||
if (isCycleAllowed) {
|
||||
index = (index + listLength) % listLength;
|
||||
}
|
||||
return list[Math.max(0, Math.min(index, listLength - 1))];
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap dom/event-handler.js
|
||||
@@ -306,7 +60,6 @@ const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
@@ -475,33 +228,11 @@ const EventHandler = {
|
||||
if (typeof event !== 'string' || !element) {
|
||||
return null;
|
||||
}
|
||||
const $ = getjQuery();
|
||||
const typeEvent = getTypeEvent(event);
|
||||
const inNamespace = event !== typeEvent;
|
||||
let jQueryEvent = null;
|
||||
let bubbles = true;
|
||||
let nativeDispatch = true;
|
||||
let defaultPrevented = false;
|
||||
if (inNamespace && $) {
|
||||
jQueryEvent = $.Event(event, args);
|
||||
$(element).trigger(jQueryEvent);
|
||||
bubbles = !jQueryEvent.isPropagationStopped();
|
||||
nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
|
||||
defaultPrevented = jQueryEvent.isDefaultPrevented();
|
||||
}
|
||||
const evt = hydrateObj(new Event(event, {
|
||||
bubbles,
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
}), args);
|
||||
if (defaultPrevented) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
if (nativeDispatch) {
|
||||
element.dispatchEvent(evt);
|
||||
}
|
||||
if (evt.defaultPrevented && jQueryEvent) {
|
||||
jQueryEvent.preventDefault();
|
||||
}
|
||||
element.dispatchEvent(evt);
|
||||
return evt;
|
||||
}
|
||||
};
|
||||
@@ -578,6 +309,210 @@ const Manipulator = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/index.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const MAX_UID = 1000000;
|
||||
const MILLISECONDS_MULTIPLIER = 1000;
|
||||
const TRANSITION_END = 'transitionend';
|
||||
|
||||
/**
|
||||
* Properly escape IDs selectors to handle weird IDs
|
||||
* @param {string} selector
|
||||
* @returns {string}
|
||||
*/
|
||||
const parseSelector = selector => {
|
||||
if (selector && window.CSS && window.CSS.escape) {
|
||||
// document.querySelector needs escaping to handle IDs (html5+) containing for instance /
|
||||
selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`);
|
||||
}
|
||||
return selector;
|
||||
};
|
||||
|
||||
// Shout-out Angus Croll (https://goo.gl/pxwQGp)
|
||||
const toType = object => {
|
||||
if (object === null || object === undefined) {
|
||||
return `${object}`;
|
||||
}
|
||||
return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Public Util API
|
||||
*/
|
||||
|
||||
const getUID = prefix => {
|
||||
do {
|
||||
prefix += Math.floor(Math.random() * MAX_UID);
|
||||
} while (document.getElementById(prefix));
|
||||
return prefix;
|
||||
};
|
||||
const getTransitionDurationFromElement = element => {
|
||||
if (!element) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get transition-duration of the element
|
||||
let {
|
||||
transitionDuration,
|
||||
transitionDelay
|
||||
} = window.getComputedStyle(element);
|
||||
const floatTransitionDuration = Number.parseFloat(transitionDuration);
|
||||
const floatTransitionDelay = Number.parseFloat(transitionDelay);
|
||||
|
||||
// Return 0 if element or transition duration is not found
|
||||
if (!floatTransitionDuration && !floatTransitionDelay) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If multiple durations are defined, take the first
|
||||
transitionDuration = transitionDuration.split(',')[0];
|
||||
transitionDelay = transitionDelay.split(',')[0];
|
||||
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
|
||||
};
|
||||
const triggerTransitionEnd = element => {
|
||||
element.dispatchEvent(new Event(TRANSITION_END));
|
||||
};
|
||||
const isElement = object => {
|
||||
if (!object || typeof object !== 'object') {
|
||||
return false;
|
||||
}
|
||||
return typeof object.nodeType !== 'undefined';
|
||||
};
|
||||
const getElement = object => {
|
||||
if (isElement(object)) {
|
||||
return object;
|
||||
}
|
||||
if (typeof object === 'string' && object.length > 0) {
|
||||
return document.querySelector(parseSelector(object));
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const isVisible = element => {
|
||||
if (!isElement(element) || element.getClientRects().length === 0) {
|
||||
return false;
|
||||
}
|
||||
const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
||||
// Handle `details` element as its content may falsie appear visible when it is closed
|
||||
const closedDetails = element.closest('details:not([open])');
|
||||
if (!closedDetails) {
|
||||
return elementIsVisible;
|
||||
}
|
||||
if (closedDetails !== element) {
|
||||
const summary = element.closest('summary');
|
||||
if (summary && summary.parentNode !== closedDetails) {
|
||||
return false;
|
||||
}
|
||||
if (summary === null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return elementIsVisible;
|
||||
};
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
const findShadowRoot = element => {
|
||||
if (!document.documentElement.attachShadow) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Can find the shadow root otherwise it'll return the document
|
||||
if (typeof element.getRootNode === 'function') {
|
||||
const root = element.getRootNode();
|
||||
return root instanceof ShadowRoot ? root : null;
|
||||
}
|
||||
if (element instanceof ShadowRoot) {
|
||||
return element;
|
||||
}
|
||||
|
||||
// when we don't find a shadow root
|
||||
if (!element.parentNode) {
|
||||
return null;
|
||||
}
|
||||
return findShadowRoot(element.parentNode);
|
||||
};
|
||||
const noop = () => {};
|
||||
|
||||
/**
|
||||
* Trick to restart an element's animation
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @return void
|
||||
*
|
||||
* @see https://www.harrytheo.com/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||||
*/
|
||||
const reflow = element => {
|
||||
element.offsetHeight; // eslint-disable-line no-unused-expressions
|
||||
};
|
||||
const isRTL = () => document.documentElement.dir === 'rtl';
|
||||
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
|
||||
return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue;
|
||||
};
|
||||
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
|
||||
if (!waitForTransition) {
|
||||
execute(callback);
|
||||
return;
|
||||
}
|
||||
const durationPadding = 5;
|
||||
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
||||
let called = false;
|
||||
const handler = ({
|
||||
target
|
||||
}) => {
|
||||
if (target !== transitionElement) {
|
||||
return;
|
||||
}
|
||||
called = true;
|
||||
transitionElement.removeEventListener(TRANSITION_END, handler);
|
||||
execute(callback);
|
||||
};
|
||||
transitionElement.addEventListener(TRANSITION_END, handler);
|
||||
setTimeout(() => {
|
||||
if (!called) {
|
||||
triggerTransitionEnd(transitionElement);
|
||||
}
|
||||
}, emulatedDuration);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the previous/next element of a list.
|
||||
*
|
||||
* @param {array} list The list of elements
|
||||
* @param activeElement The active element
|
||||
* @param shouldGetNext Choose to get next or previous element
|
||||
* @param isCycleAllowed
|
||||
* @return {Element|elem} The proper element
|
||||
*/
|
||||
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
|
||||
const listLength = list.length;
|
||||
let index = list.indexOf(activeElement);
|
||||
|
||||
// if the element does not exist in the list return an element
|
||||
// depending on the direction and if cycle is allowed
|
||||
if (index === -1) {
|
||||
return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];
|
||||
}
|
||||
index += shouldGetNext ? 1 : -1;
|
||||
if (isCycleAllowed) {
|
||||
index = (index + listLength) % listLength;
|
||||
}
|
||||
return list[Math.max(0, Math.min(index, listLength - 1))];
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/config.js
|
||||
@@ -863,20 +798,6 @@ class Alert extends BaseComponent {
|
||||
EventHandler.trigger(this._element, EVENT_CLOSED);
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Alert.getOrCreateInstance(this);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -885,12 +806,6 @@ class Alert extends BaseComponent {
|
||||
|
||||
enableDismissTrigger(Alert, 'close');
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Alert);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap button.js
|
||||
@@ -926,16 +841,6 @@ class Button extends BaseComponent {
|
||||
// Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
|
||||
this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Button.getOrCreateInstance(this);
|
||||
if (config === 'toggle') {
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -949,12 +854,6 @@ EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event
|
||||
data.toggle();
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Button);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/swipe.js
|
||||
@@ -1391,23 +1290,6 @@ class Carousel extends BaseComponent {
|
||||
}
|
||||
return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Carousel.getOrCreateInstance(this, config);
|
||||
if (typeof config === 'number') {
|
||||
data.to(config);
|
||||
return;
|
||||
}
|
||||
if (typeof config === 'string') {
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1442,12 +1324,6 @@ EventHandler.on(window, EVENT_LOAD_DATA_API$3, () => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Carousel);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap collapse.js
|
||||
@@ -1641,23 +1517,6 @@ class Collapse extends BaseComponent {
|
||||
element.setAttribute('aria-expanded', isOpen);
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
const _config = {};
|
||||
if (typeof config === 'string' && /show|hide/.test(config)) {
|
||||
_config.toggle = false;
|
||||
}
|
||||
return this.each(function () {
|
||||
const data = Collapse.getOrCreateInstance(this, _config);
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1676,12 +1535,6 @@ EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, functi
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Collapse);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap dropdown.js
|
||||
@@ -1955,20 +1808,6 @@ class Dropdown extends BaseComponent {
|
||||
// allow cycling to get the last item in case key equals ARROW_UP_KEY
|
||||
getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus();
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Dropdown.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
static clearMenus(event) {
|
||||
if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) {
|
||||
return;
|
||||
@@ -2044,12 +1883,6 @@ EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, functi
|
||||
Dropdown.getOrCreateInstance(this).toggle();
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Dropdown);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/backdrop.js
|
||||
@@ -2622,20 +2455,6 @@ class Modal extends BaseComponent {
|
||||
this._element.style.paddingLeft = '';
|
||||
this._element.style.paddingRight = '';
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config, relatedTarget) {
|
||||
return this.each(function () {
|
||||
const data = Modal.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](relatedTarget);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2669,12 +2488,6 @@ EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, functi
|
||||
});
|
||||
enableDismissTrigger(Modal);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Modal);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap offcanvas.js
|
||||
@@ -2843,20 +2656,6 @@ class Offcanvas extends BaseComponent {
|
||||
EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
|
||||
});
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Offcanvas.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2900,12 +2699,6 @@ EventHandler.on(window, EVENT_RESIZE, () => {
|
||||
});
|
||||
enableDismissTrigger(Offcanvas);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Offcanvas);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/sanitizer.js
|
||||
@@ -3627,28 +3420,8 @@ class Tooltip extends BaseComponent {
|
||||
this.tip = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Tooltip.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Tooltip);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap popover.js
|
||||
@@ -3708,28 +3481,8 @@ class Popover extends Tooltip {
|
||||
_getContent() {
|
||||
return this._resolvePossibleFunction(this._config.content);
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Popover.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Popover);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap scrollspy.js
|
||||
@@ -3958,20 +3711,6 @@ class ScrollSpy extends BaseComponent {
|
||||
node.classList.remove(CLASS_NAME_ACTIVE$1);
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = ScrollSpy.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3984,12 +3723,6 @@ EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(ScrollSpy);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap tab.js
|
||||
@@ -4216,20 +3949,6 @@ class Tab extends BaseComponent {
|
||||
_getOuterElement(elem) {
|
||||
return elem.closest(SELECTOR_OUTER) || elem;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Tab.getOrCreateInstance(this);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4254,11 +3973,6 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
||||
Tab.getOrCreateInstance(element);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Tab);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
@@ -4416,19 +4130,6 @@ class Toast extends BaseComponent {
|
||||
clearTimeout(this._timeout);
|
||||
this._timeout = null;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Toast.getOrCreateInstance(this, config);
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4437,11 +4138,5 @@ class Toast extends BaseComponent {
|
||||
|
||||
enableDismissTrigger(Toast);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Toast);
|
||||
|
||||
export { Alert, Button, Carousel, Collapse, Dropdown, Modal, Offcanvas, Popover, ScrollSpy, Tab, Toast, Tooltip };
|
||||
//# sourceMappingURL=bootstrap.esm.js.map
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+206
-511
@@ -76,252 +76,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/index.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const MAX_UID = 1000000;
|
||||
const MILLISECONDS_MULTIPLIER = 1000;
|
||||
const TRANSITION_END = 'transitionend';
|
||||
|
||||
/**
|
||||
* Properly escape IDs selectors to handle weird IDs
|
||||
* @param {string} selector
|
||||
* @returns {string}
|
||||
*/
|
||||
const parseSelector = selector => {
|
||||
if (selector && window.CSS && window.CSS.escape) {
|
||||
// document.querySelector needs escaping to handle IDs (html5+) containing for instance /
|
||||
selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`);
|
||||
}
|
||||
return selector;
|
||||
};
|
||||
|
||||
// Shout-out Angus Croll (https://goo.gl/pxwQGp)
|
||||
const toType = object => {
|
||||
if (object === null || object === undefined) {
|
||||
return `${object}`;
|
||||
}
|
||||
return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Public Util API
|
||||
*/
|
||||
|
||||
const getUID = prefix => {
|
||||
do {
|
||||
prefix += Math.floor(Math.random() * MAX_UID);
|
||||
} while (document.getElementById(prefix));
|
||||
return prefix;
|
||||
};
|
||||
const getTransitionDurationFromElement = element => {
|
||||
if (!element) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get transition-duration of the element
|
||||
let {
|
||||
transitionDuration,
|
||||
transitionDelay
|
||||
} = window.getComputedStyle(element);
|
||||
const floatTransitionDuration = Number.parseFloat(transitionDuration);
|
||||
const floatTransitionDelay = Number.parseFloat(transitionDelay);
|
||||
|
||||
// Return 0 if element or transition duration is not found
|
||||
if (!floatTransitionDuration && !floatTransitionDelay) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If multiple durations are defined, take the first
|
||||
transitionDuration = transitionDuration.split(',')[0];
|
||||
transitionDelay = transitionDelay.split(',')[0];
|
||||
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
|
||||
};
|
||||
const triggerTransitionEnd = element => {
|
||||
element.dispatchEvent(new Event(TRANSITION_END));
|
||||
};
|
||||
const isElement = object => {
|
||||
if (!object || typeof object !== 'object') {
|
||||
return false;
|
||||
}
|
||||
if (typeof object.jquery !== 'undefined') {
|
||||
object = object[0];
|
||||
}
|
||||
return typeof object.nodeType !== 'undefined';
|
||||
};
|
||||
const getElement = object => {
|
||||
// it's a jQuery object or a node element
|
||||
if (isElement(object)) {
|
||||
return object.jquery ? object[0] : object;
|
||||
}
|
||||
if (typeof object === 'string' && object.length > 0) {
|
||||
return document.querySelector(parseSelector(object));
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const isVisible = element => {
|
||||
if (!isElement(element) || element.getClientRects().length === 0) {
|
||||
return false;
|
||||
}
|
||||
const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
||||
// Handle `details` element as its content may falsie appear visible when it is closed
|
||||
const closedDetails = element.closest('details:not([open])');
|
||||
if (!closedDetails) {
|
||||
return elementIsVisible;
|
||||
}
|
||||
if (closedDetails !== element) {
|
||||
const summary = element.closest('summary');
|
||||
if (summary && summary.parentNode !== closedDetails) {
|
||||
return false;
|
||||
}
|
||||
if (summary === null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return elementIsVisible;
|
||||
};
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
const findShadowRoot = element => {
|
||||
if (!document.documentElement.attachShadow) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Can find the shadow root otherwise it'll return the document
|
||||
if (typeof element.getRootNode === 'function') {
|
||||
const root = element.getRootNode();
|
||||
return root instanceof ShadowRoot ? root : null;
|
||||
}
|
||||
if (element instanceof ShadowRoot) {
|
||||
return element;
|
||||
}
|
||||
|
||||
// when we don't find a shadow root
|
||||
if (!element.parentNode) {
|
||||
return null;
|
||||
}
|
||||
return findShadowRoot(element.parentNode);
|
||||
};
|
||||
const noop = () => {};
|
||||
|
||||
/**
|
||||
* Trick to restart an element's animation
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @return void
|
||||
*
|
||||
* @see https://www.harrytheo.com/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||||
*/
|
||||
const reflow = element => {
|
||||
element.offsetHeight; // eslint-disable-line no-unused-expressions
|
||||
};
|
||||
const getjQuery = () => {
|
||||
if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return window.jQuery;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
for (const callback of DOMContentLoadedCallbacks) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
const isRTL = () => document.documentElement.dir === 'rtl';
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
|
||||
return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue;
|
||||
};
|
||||
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
|
||||
if (!waitForTransition) {
|
||||
execute(callback);
|
||||
return;
|
||||
}
|
||||
const durationPadding = 5;
|
||||
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
||||
let called = false;
|
||||
const handler = ({
|
||||
target
|
||||
}) => {
|
||||
if (target !== transitionElement) {
|
||||
return;
|
||||
}
|
||||
called = true;
|
||||
transitionElement.removeEventListener(TRANSITION_END, handler);
|
||||
execute(callback);
|
||||
};
|
||||
transitionElement.addEventListener(TRANSITION_END, handler);
|
||||
setTimeout(() => {
|
||||
if (!called) {
|
||||
triggerTransitionEnd(transitionElement);
|
||||
}
|
||||
}, emulatedDuration);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the previous/next element of a list.
|
||||
*
|
||||
* @param {array} list The list of elements
|
||||
* @param activeElement The active element
|
||||
* @param shouldGetNext Choose to get next or previous element
|
||||
* @param isCycleAllowed
|
||||
* @return {Element|elem} The proper element
|
||||
*/
|
||||
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
|
||||
const listLength = list.length;
|
||||
let index = list.indexOf(activeElement);
|
||||
|
||||
// if the element does not exist in the list return an element
|
||||
// depending on the direction and if cycle is allowed
|
||||
if (index === -1) {
|
||||
return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];
|
||||
}
|
||||
index += shouldGetNext ? 1 : -1;
|
||||
if (isCycleAllowed) {
|
||||
index = (index + listLength) % listLength;
|
||||
}
|
||||
return list[Math.max(0, Math.min(index, listLength - 1))];
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap dom/event-handler.js
|
||||
@@ -329,7 +83,6 @@
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
@@ -498,33 +251,11 @@
|
||||
if (typeof event !== 'string' || !element) {
|
||||
return null;
|
||||
}
|
||||
const $ = getjQuery();
|
||||
const typeEvent = getTypeEvent(event);
|
||||
const inNamespace = event !== typeEvent;
|
||||
let jQueryEvent = null;
|
||||
let bubbles = true;
|
||||
let nativeDispatch = true;
|
||||
let defaultPrevented = false;
|
||||
if (inNamespace && $) {
|
||||
jQueryEvent = $.Event(event, args);
|
||||
$(element).trigger(jQueryEvent);
|
||||
bubbles = !jQueryEvent.isPropagationStopped();
|
||||
nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
|
||||
defaultPrevented = jQueryEvent.isDefaultPrevented();
|
||||
}
|
||||
const evt = hydrateObj(new Event(event, {
|
||||
bubbles,
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
}), args);
|
||||
if (defaultPrevented) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
if (nativeDispatch) {
|
||||
element.dispatchEvent(evt);
|
||||
}
|
||||
if (evt.defaultPrevented && jQueryEvent) {
|
||||
jQueryEvent.preventDefault();
|
||||
}
|
||||
element.dispatchEvent(evt);
|
||||
return evt;
|
||||
}
|
||||
};
|
||||
@@ -601,6 +332,210 @@
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/index.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const MAX_UID = 1000000;
|
||||
const MILLISECONDS_MULTIPLIER = 1000;
|
||||
const TRANSITION_END = 'transitionend';
|
||||
|
||||
/**
|
||||
* Properly escape IDs selectors to handle weird IDs
|
||||
* @param {string} selector
|
||||
* @returns {string}
|
||||
*/
|
||||
const parseSelector = selector => {
|
||||
if (selector && window.CSS && window.CSS.escape) {
|
||||
// document.querySelector needs escaping to handle IDs (html5+) containing for instance /
|
||||
selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`);
|
||||
}
|
||||
return selector;
|
||||
};
|
||||
|
||||
// Shout-out Angus Croll (https://goo.gl/pxwQGp)
|
||||
const toType = object => {
|
||||
if (object === null || object === undefined) {
|
||||
return `${object}`;
|
||||
}
|
||||
return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Public Util API
|
||||
*/
|
||||
|
||||
const getUID = prefix => {
|
||||
do {
|
||||
prefix += Math.floor(Math.random() * MAX_UID);
|
||||
} while (document.getElementById(prefix));
|
||||
return prefix;
|
||||
};
|
||||
const getTransitionDurationFromElement = element => {
|
||||
if (!element) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get transition-duration of the element
|
||||
let {
|
||||
transitionDuration,
|
||||
transitionDelay
|
||||
} = window.getComputedStyle(element);
|
||||
const floatTransitionDuration = Number.parseFloat(transitionDuration);
|
||||
const floatTransitionDelay = Number.parseFloat(transitionDelay);
|
||||
|
||||
// Return 0 if element or transition duration is not found
|
||||
if (!floatTransitionDuration && !floatTransitionDelay) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If multiple durations are defined, take the first
|
||||
transitionDuration = transitionDuration.split(',')[0];
|
||||
transitionDelay = transitionDelay.split(',')[0];
|
||||
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
|
||||
};
|
||||
const triggerTransitionEnd = element => {
|
||||
element.dispatchEvent(new Event(TRANSITION_END));
|
||||
};
|
||||
const isElement = object => {
|
||||
if (!object || typeof object !== 'object') {
|
||||
return false;
|
||||
}
|
||||
return typeof object.nodeType !== 'undefined';
|
||||
};
|
||||
const getElement = object => {
|
||||
if (isElement(object)) {
|
||||
return object;
|
||||
}
|
||||
if (typeof object === 'string' && object.length > 0) {
|
||||
return document.querySelector(parseSelector(object));
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const isVisible = element => {
|
||||
if (!isElement(element) || element.getClientRects().length === 0) {
|
||||
return false;
|
||||
}
|
||||
const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
||||
// Handle `details` element as its content may falsie appear visible when it is closed
|
||||
const closedDetails = element.closest('details:not([open])');
|
||||
if (!closedDetails) {
|
||||
return elementIsVisible;
|
||||
}
|
||||
if (closedDetails !== element) {
|
||||
const summary = element.closest('summary');
|
||||
if (summary && summary.parentNode !== closedDetails) {
|
||||
return false;
|
||||
}
|
||||
if (summary === null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return elementIsVisible;
|
||||
};
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
const findShadowRoot = element => {
|
||||
if (!document.documentElement.attachShadow) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Can find the shadow root otherwise it'll return the document
|
||||
if (typeof element.getRootNode === 'function') {
|
||||
const root = element.getRootNode();
|
||||
return root instanceof ShadowRoot ? root : null;
|
||||
}
|
||||
if (element instanceof ShadowRoot) {
|
||||
return element;
|
||||
}
|
||||
|
||||
// when we don't find a shadow root
|
||||
if (!element.parentNode) {
|
||||
return null;
|
||||
}
|
||||
return findShadowRoot(element.parentNode);
|
||||
};
|
||||
const noop = () => {};
|
||||
|
||||
/**
|
||||
* Trick to restart an element's animation
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @return void
|
||||
*
|
||||
* @see https://www.harrytheo.com/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||||
*/
|
||||
const reflow = element => {
|
||||
element.offsetHeight; // eslint-disable-line no-unused-expressions
|
||||
};
|
||||
const isRTL = () => document.documentElement.dir === 'rtl';
|
||||
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
|
||||
return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue;
|
||||
};
|
||||
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
|
||||
if (!waitForTransition) {
|
||||
execute(callback);
|
||||
return;
|
||||
}
|
||||
const durationPadding = 5;
|
||||
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
||||
let called = false;
|
||||
const handler = ({
|
||||
target
|
||||
}) => {
|
||||
if (target !== transitionElement) {
|
||||
return;
|
||||
}
|
||||
called = true;
|
||||
transitionElement.removeEventListener(TRANSITION_END, handler);
|
||||
execute(callback);
|
||||
};
|
||||
transitionElement.addEventListener(TRANSITION_END, handler);
|
||||
setTimeout(() => {
|
||||
if (!called) {
|
||||
triggerTransitionEnd(transitionElement);
|
||||
}
|
||||
}, emulatedDuration);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the previous/next element of a list.
|
||||
*
|
||||
* @param {array} list The list of elements
|
||||
* @param activeElement The active element
|
||||
* @param shouldGetNext Choose to get next or previous element
|
||||
* @param isCycleAllowed
|
||||
* @return {Element|elem} The proper element
|
||||
*/
|
||||
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
|
||||
const listLength = list.length;
|
||||
let index = list.indexOf(activeElement);
|
||||
|
||||
// if the element does not exist in the list return an element
|
||||
// depending on the direction and if cycle is allowed
|
||||
if (index === -1) {
|
||||
return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];
|
||||
}
|
||||
index += shouldGetNext ? 1 : -1;
|
||||
if (isCycleAllowed) {
|
||||
index = (index + listLength) % listLength;
|
||||
}
|
||||
return list[Math.max(0, Math.min(index, listLength - 1))];
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/config.js
|
||||
@@ -886,20 +821,6 @@
|
||||
EventHandler.trigger(this._element, EVENT_CLOSED);
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Alert.getOrCreateInstance(this);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -908,12 +829,6 @@
|
||||
|
||||
enableDismissTrigger(Alert, 'close');
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Alert);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap button.js
|
||||
@@ -949,16 +864,6 @@
|
||||
// Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
|
||||
this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Button.getOrCreateInstance(this);
|
||||
if (config === 'toggle') {
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -972,12 +877,6 @@
|
||||
data.toggle();
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Button);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/swipe.js
|
||||
@@ -1414,23 +1313,6 @@
|
||||
}
|
||||
return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Carousel.getOrCreateInstance(this, config);
|
||||
if (typeof config === 'number') {
|
||||
data.to(config);
|
||||
return;
|
||||
}
|
||||
if (typeof config === 'string') {
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1465,12 +1347,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Carousel);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap collapse.js
|
||||
@@ -1664,23 +1540,6 @@
|
||||
element.setAttribute('aria-expanded', isOpen);
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
const _config = {};
|
||||
if (typeof config === 'string' && /show|hide/.test(config)) {
|
||||
_config.toggle = false;
|
||||
}
|
||||
return this.each(function () {
|
||||
const data = Collapse.getOrCreateInstance(this, _config);
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1699,12 +1558,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Collapse);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap dropdown.js
|
||||
@@ -1978,20 +1831,6 @@
|
||||
// allow cycling to get the last item in case key equals ARROW_UP_KEY
|
||||
getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus();
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Dropdown.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
static clearMenus(event) {
|
||||
if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) {
|
||||
return;
|
||||
@@ -2067,12 +1906,6 @@
|
||||
Dropdown.getOrCreateInstance(this).toggle();
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Dropdown);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/backdrop.js
|
||||
@@ -2645,20 +2478,6 @@
|
||||
this._element.style.paddingLeft = '';
|
||||
this._element.style.paddingRight = '';
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config, relatedTarget) {
|
||||
return this.each(function () {
|
||||
const data = Modal.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](relatedTarget);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2692,12 +2511,6 @@
|
||||
});
|
||||
enableDismissTrigger(Modal);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Modal);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap offcanvas.js
|
||||
@@ -2866,20 +2679,6 @@
|
||||
EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
|
||||
});
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Offcanvas.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2923,12 +2722,6 @@
|
||||
});
|
||||
enableDismissTrigger(Offcanvas);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Offcanvas);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/sanitizer.js
|
||||
@@ -3650,28 +3443,8 @@
|
||||
this.tip = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Tooltip.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Tooltip);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap popover.js
|
||||
@@ -3731,28 +3504,8 @@
|
||||
_getContent() {
|
||||
return this._resolvePossibleFunction(this._config.content);
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Popover.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Popover);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap scrollspy.js
|
||||
@@ -3981,20 +3734,6 @@
|
||||
node.classList.remove(CLASS_NAME_ACTIVE$1);
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = ScrollSpy.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4007,12 +3746,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(ScrollSpy);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap tab.js
|
||||
@@ -4239,20 +3972,6 @@
|
||||
_getOuterElement(elem) {
|
||||
return elem.closest(SELECTOR_OUTER) || elem;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Tab.getOrCreateInstance(this);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4277,11 +3996,6 @@
|
||||
Tab.getOrCreateInstance(element);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Tab);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
@@ -4439,19 +4153,6 @@
|
||||
clearTimeout(this._timeout);
|
||||
this._timeout = null;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Toast.getOrCreateInstance(this, config);
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4460,12 +4161,6 @@
|
||||
|
||||
enableDismissTrigger(Toast);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Toast);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap index.umd.js
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+4
-24
@@ -4,10 +4,10 @@
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./util/component-functions.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './util/component-functions', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Alert = factory(global.BaseComponent, global.EventHandler, global.ComponentFunctions, global.Index));
|
||||
})(this, (function (BaseComponent, EventHandler, componentFunctions_js, index_js) { 'use strict';
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./util/component-functions.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './util/component-functions'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Alert = factory(global.BaseComponent, global.EventHandler, global.ComponentFunctions));
|
||||
})(this, (function (BaseComponent, EventHandler, componentFunctions_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
@@ -56,20 +56,6 @@
|
||||
EventHandler.trigger(this._element, EVENT_CLOSED);
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Alert.getOrCreateInstance(this);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,12 +64,6 @@
|
||||
|
||||
componentFunctions_js.enableDismissTrigger(Alert, 'close');
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Alert);
|
||||
|
||||
return Alert;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"alert.js","sources":["../src/alert.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'alert'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE)\n\n if (closeEvent.defaultPrevented) {\n return\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE)\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated)\n }\n\n // Private\n _destroyElement() {\n this._element.remove()\n EventHandler.trigger(this._element, EVENT_CLOSED)\n this.dispose()\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Alert.getOrCreateInstance(this)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close')\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Alert)\n\nexport default Alert\n"],"names":["NAME","DATA_KEY","EVENT_KEY","EVENT_CLOSE","EVENT_CLOSED","CLASS_NAME_FADE","CLASS_NAME_SHOW","Alert","BaseComponent","close","closeEvent","EventHandler","trigger","_element","defaultPrevented","classList","remove","isAnimated","contains","_queueCallback","_destroyElement","dispose","jQueryInterface","config","each","data","getOrCreateInstance","undefined","startsWith","TypeError","enableDismissTrigger","defineJQueryPlugin"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAOA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,OAAO;EACpB,MAAMC,QAAQ,GAAG,UAAU;EAC3B,MAAMC,SAAS,GAAG,CAAA,CAAA,EAAID,QAAQ,CAAA,CAAE;EAEhC,MAAME,WAAW,GAAG,CAAA,KAAA,EAAQD,SAAS,CAAA,CAAE;EACvC,MAAME,YAAY,GAAG,CAAA,MAAA,EAASF,SAAS,CAAA,CAAE;EACzC,MAAMG,eAAe,GAAG,MAAM;EAC9B,MAAMC,eAAe,GAAG,MAAM;;EAE9B;EACA;EACA;;EAEA,MAAMC,KAAK,SAASC,aAAa,CAAC;EAChC;IACA,WAAWR,IAAIA,GAAG;EAChB,IAAA,OAAOA,IAAI;EACb,EAAA;;EAEA;EACAS,EAAAA,KAAKA,GAAG;MACN,MAAMC,UAAU,GAAGC,YAAY,CAACC,OAAO,CAAC,IAAI,CAACC,QAAQ,EAAEV,WAAW,CAAC;MAEnE,IAAIO,UAAU,CAACI,gBAAgB,EAAE;EAC/B,MAAA;EACF,IAAA;MAEA,IAAI,CAACD,QAAQ,CAACE,SAAS,CAACC,MAAM,CAACV,eAAe,CAAC;MAE/C,MAAMW,UAAU,GAAG,IAAI,CAACJ,QAAQ,CAACE,SAAS,CAACG,QAAQ,CAACb,eAAe,CAAC;EACpE,IAAA,IAAI,CAACc,cAAc,CAAC,MAAM,IAAI,CAACC,eAAe,EAAE,EAAE,IAAI,CAACP,QAAQ,EAAEI,UAAU,CAAC;EAC9E,EAAA;;EAEA;EACAG,EAAAA,eAAeA,GAAG;EAChB,IAAA,IAAI,CAACP,QAAQ,CAACG,MAAM,EAAE;MACtBL,YAAY,CAACC,OAAO,CAAC,IAAI,CAACC,QAAQ,EAAET,YAAY,CAAC;MACjD,IAAI,CAACiB,OAAO,EAAE;EAChB,EAAA;;EAEA;IACA,OAAOC,eAAeA,CAACC,MAAM,EAAE;EAC7B,IAAA,OAAO,IAAI,CAACC,IAAI,CAAC,YAAY;EAC3B,MAAA,MAAMC,IAAI,GAAGlB,KAAK,CAACmB,mBAAmB,CAAC,IAAI,CAAC;EAE5C,MAAA,IAAI,OAAOH,MAAM,KAAK,QAAQ,EAAE;EAC9B,QAAA;EACF,MAAA;EAEA,MAAA,IAAIE,IAAI,CAACF,MAAM,CAAC,KAAKI,SAAS,IAAIJ,MAAM,CAACK,UAAU,CAAC,GAAG,CAAC,IAAIL,MAAM,KAAK,aAAa,EAAE;EACpF,QAAA,MAAM,IAAIM,SAAS,CAAC,CAAA,iBAAA,EAAoBN,MAAM,GAAG,CAAC;EACpD,MAAA;EAEAE,MAAAA,IAAI,CAACF,MAAM,CAAC,CAAC,IAAI,CAAC;EACpB,IAAA,CAAC,CAAC;EACJ,EAAA;EACF;;EAEA;EACA;EACA;;AAEAO,4CAAoB,CAACvB,KAAK,EAAE,OAAO,CAAC;;EAEpC;EACA;EACA;;AAEAwB,6BAAkB,CAACxB,KAAK,CAAC;;;;;;;;"}
|
||||
{"version":3,"file":"alert.js","sources":["../src/alert.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'alert'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE)\n\n if (closeEvent.defaultPrevented) {\n return\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE)\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated)\n }\n\n // Private\n _destroyElement() {\n this._element.remove()\n EventHandler.trigger(this._element, EVENT_CLOSED)\n this.dispose()\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close')\n\nexport default Alert\n"],"names":["NAME","DATA_KEY","EVENT_KEY","EVENT_CLOSE","EVENT_CLOSED","CLASS_NAME_FADE","CLASS_NAME_SHOW","Alert","BaseComponent","close","closeEvent","EventHandler","trigger","_element","defaultPrevented","classList","remove","isAnimated","contains","_queueCallback","_destroyElement","dispose","enableDismissTrigger"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAMA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,OAAO;EACpB,MAAMC,QAAQ,GAAG,UAAU;EAC3B,MAAMC,SAAS,GAAG,CAAA,CAAA,EAAID,QAAQ,CAAA,CAAE;EAEhC,MAAME,WAAW,GAAG,CAAA,KAAA,EAAQD,SAAS,CAAA,CAAE;EACvC,MAAME,YAAY,GAAG,CAAA,MAAA,EAASF,SAAS,CAAA,CAAE;EACzC,MAAMG,eAAe,GAAG,MAAM;EAC9B,MAAMC,eAAe,GAAG,MAAM;;EAE9B;EACA;EACA;;EAEA,MAAMC,KAAK,SAASC,aAAa,CAAC;EAChC;IACA,WAAWR,IAAIA,GAAG;EAChB,IAAA,OAAOA,IAAI;EACb,EAAA;;EAEA;EACAS,EAAAA,KAAKA,GAAG;MACN,MAAMC,UAAU,GAAGC,YAAY,CAACC,OAAO,CAAC,IAAI,CAACC,QAAQ,EAAEV,WAAW,CAAC;MAEnE,IAAIO,UAAU,CAACI,gBAAgB,EAAE;EAC/B,MAAA;EACF,IAAA;MAEA,IAAI,CAACD,QAAQ,CAACE,SAAS,CAACC,MAAM,CAACV,eAAe,CAAC;MAE/C,MAAMW,UAAU,GAAG,IAAI,CAACJ,QAAQ,CAACE,SAAS,CAACG,QAAQ,CAACb,eAAe,CAAC;EACpE,IAAA,IAAI,CAACc,cAAc,CAAC,MAAM,IAAI,CAACC,eAAe,EAAE,EAAE,IAAI,CAACP,QAAQ,EAAEI,UAAU,CAAC;EAC9E,EAAA;;EAEA;EACAG,EAAAA,eAAeA,GAAG;EAChB,IAAA,IAAI,CAACP,QAAQ,CAACG,MAAM,EAAE;MACtBL,YAAY,CAACC,OAAO,CAAC,IAAI,CAACC,QAAQ,EAAET,YAAY,CAAC;MACjD,IAAI,CAACiB,OAAO,EAAE;EAChB,EAAA;EACF;;EAEA;EACA;EACA;;AAEAC,4CAAoB,CAACf,KAAK,EAAE,OAAO,CAAC;;;;;;;;"}
|
||||
Vendored
+4
-20
@@ -4,10 +4,10 @@
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Button = factory(global.BaseComponent, global.EventHandler, global.Index));
|
||||
})(this, (function (BaseComponent, EventHandler, index_js) { 'use strict';
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Button = factory(global.BaseComponent, global.EventHandler));
|
||||
})(this, (function (BaseComponent, EventHandler) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
@@ -44,16 +44,6 @@
|
||||
// Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
|
||||
this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE));
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Button.getOrCreateInstance(this);
|
||||
if (config === 'toggle') {
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,12 +57,6 @@
|
||||
data.toggle();
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Button);
|
||||
|
||||
return Button;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"button.js","sources":["../src/button.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'button'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"button\"]'\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE))\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Button.getOrCreateInstance(this)\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {\n event.preventDefault()\n\n const button = event.target.closest(SELECTOR_DATA_TOGGLE)\n const data = Button.getOrCreateInstance(button)\n\n data.toggle()\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Button)\n\nexport default Button\n"],"names":["NAME","DATA_KEY","EVENT_KEY","DATA_API_KEY","CLASS_NAME_ACTIVE","SELECTOR_DATA_TOGGLE","EVENT_CLICK_DATA_API","Button","BaseComponent","toggle","_element","setAttribute","classList","jQueryInterface","config","each","data","getOrCreateInstance","EventHandler","on","document","event","preventDefault","button","target","closest","defineJQueryPlugin"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAMA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,QAAQ;EACrB,MAAMC,QAAQ,GAAG,WAAW;EAC5B,MAAMC,SAAS,GAAG,CAAA,CAAA,EAAID,QAAQ,CAAA,CAAE;EAChC,MAAME,YAAY,GAAG,WAAW;EAEhC,MAAMC,iBAAiB,GAAG,QAAQ;EAClC,MAAMC,oBAAoB,GAAG,2BAA2B;EACxD,MAAMC,oBAAoB,GAAG,CAAA,KAAA,EAAQJ,SAAS,CAAA,EAAGC,YAAY,CAAA,CAAE;;EAE/D;EACA;EACA;;EAEA,MAAMI,MAAM,SAASC,aAAa,CAAC;EACjC;IACA,WAAWR,IAAIA,GAAG;EAChB,IAAA,OAAOA,IAAI;EACb,EAAA;;EAEA;EACAS,EAAAA,MAAMA,GAAG;EACP;EACA,IAAA,IAAI,CAACC,QAAQ,CAACC,YAAY,CAAC,cAAc,EAAE,IAAI,CAACD,QAAQ,CAACE,SAAS,CAACH,MAAM,CAACL,iBAAiB,CAAC,CAAC;EAC/F,EAAA;;EAEA;IACA,OAAOS,eAAeA,CAACC,MAAM,EAAE;EAC7B,IAAA,OAAO,IAAI,CAACC,IAAI,CAAC,YAAY;EAC3B,MAAA,MAAMC,IAAI,GAAGT,MAAM,CAACU,mBAAmB,CAAC,IAAI,CAAC;QAE7C,IAAIH,MAAM,KAAK,QAAQ,EAAE;EACvBE,QAAAA,IAAI,CAACF,MAAM,CAAC,EAAE;EAChB,MAAA;EACF,IAAA,CAAC,CAAC;EACJ,EAAA;EACF;;EAEA;EACA;EACA;;EAEAI,YAAY,CAACC,EAAE,CAACC,QAAQ,EAAEd,oBAAoB,EAAED,oBAAoB,EAAEgB,KAAK,IAAI;IAC7EA,KAAK,CAACC,cAAc,EAAE;IAEtB,MAAMC,MAAM,GAAGF,KAAK,CAACG,MAAM,CAACC,OAAO,CAACpB,oBAAoB,CAAC;EACzD,EAAA,MAAMW,IAAI,GAAGT,MAAM,CAACU,mBAAmB,CAACM,MAAM,CAAC;IAE/CP,IAAI,CAACP,MAAM,EAAE;EACf,CAAC,CAAC;;EAEF;EACA;EACA;;AAEAiB,6BAAkB,CAACnB,MAAM,CAAC;;;;;;;;"}
|
||||
{"version":3,"file":"button.js","sources":["../src/button.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'button'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"button\"]'\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE))\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {\n event.preventDefault()\n\n const button = event.target.closest(SELECTOR_DATA_TOGGLE)\n const data = Button.getOrCreateInstance(button)\n\n data.toggle()\n})\n\nexport default Button\n"],"names":["NAME","DATA_KEY","EVENT_KEY","DATA_API_KEY","CLASS_NAME_ACTIVE","SELECTOR_DATA_TOGGLE","EVENT_CLICK_DATA_API","Button","BaseComponent","toggle","_element","setAttribute","classList","EventHandler","on","document","event","preventDefault","button","target","closest","data","getOrCreateInstance"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAKA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,QAAQ;EACrB,MAAMC,QAAQ,GAAG,WAAW;EAC5B,MAAMC,SAAS,GAAG,CAAA,CAAA,EAAID,QAAQ,CAAA,CAAE;EAChC,MAAME,YAAY,GAAG,WAAW;EAEhC,MAAMC,iBAAiB,GAAG,QAAQ;EAClC,MAAMC,oBAAoB,GAAG,2BAA2B;EACxD,MAAMC,oBAAoB,GAAG,CAAA,KAAA,EAAQJ,SAAS,CAAA,EAAGC,YAAY,CAAA,CAAE;;EAE/D;EACA;EACA;;EAEA,MAAMI,MAAM,SAASC,aAAa,CAAC;EACjC;IACA,WAAWR,IAAIA,GAAG;EAChB,IAAA,OAAOA,IAAI;EACb,EAAA;;EAEA;EACAS,EAAAA,MAAMA,GAAG;EACP;EACA,IAAA,IAAI,CAACC,QAAQ,CAACC,YAAY,CAAC,cAAc,EAAE,IAAI,CAACD,QAAQ,CAACE,SAAS,CAACH,MAAM,CAACL,iBAAiB,CAAC,CAAC;EAC/F,EAAA;EACF;;EAEA;EACA;EACA;;EAEAS,YAAY,CAACC,EAAE,CAACC,QAAQ,EAAET,oBAAoB,EAAED,oBAAoB,EAAEW,KAAK,IAAI;IAC7EA,KAAK,CAACC,cAAc,EAAE;IAEtB,MAAMC,MAAM,GAAGF,KAAK,CAACG,MAAM,CAACC,OAAO,CAACf,oBAAoB,CAAC;EACzD,EAAA,MAAMgB,IAAI,GAAGd,MAAM,CAACe,mBAAmB,CAACJ,MAAM,CAAC;IAE/CG,IAAI,CAACZ,MAAM,EAAE;EACf,CAAC,CAAC;;;;;;;;"}
|
||||
Vendored
-23
@@ -325,23 +325,6 @@
|
||||
}
|
||||
return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Carousel.getOrCreateInstance(this, config);
|
||||
if (typeof config === 'number') {
|
||||
data.to(config);
|
||||
return;
|
||||
}
|
||||
if (typeof config === 'string') {
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,12 +359,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Carousel);
|
||||
|
||||
return Carousel;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
-23
@@ -202,23 +202,6 @@
|
||||
element.setAttribute('aria-expanded', isOpen);
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
const _config = {};
|
||||
if (typeof config === 'string' && /show|hide/.test(config)) {
|
||||
_config.toggle = false;
|
||||
}
|
||||
return this.each(function () {
|
||||
const data = Collapse.getOrCreateInstance(this, _config);
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,12 +220,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Collapse);
|
||||
|
||||
return Collapse;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+6
-29
@@ -4,10 +4,10 @@
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['../util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.EventHandler = factory(global.Index));
|
||||
})(this, (function (index_js) { 'use strict';
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.EventHandler = factory());
|
||||
})(this, (function () { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
@@ -16,7 +16,6 @@
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
@@ -185,33 +184,11 @@
|
||||
if (typeof event !== 'string' || !element) {
|
||||
return null;
|
||||
}
|
||||
const $ = index_js.getjQuery();
|
||||
const typeEvent = getTypeEvent(event);
|
||||
const inNamespace = event !== typeEvent;
|
||||
let jQueryEvent = null;
|
||||
let bubbles = true;
|
||||
let nativeDispatch = true;
|
||||
let defaultPrevented = false;
|
||||
if (inNamespace && $) {
|
||||
jQueryEvent = $.Event(event, args);
|
||||
$(element).trigger(jQueryEvent);
|
||||
bubbles = !jQueryEvent.isPropagationStopped();
|
||||
nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
|
||||
defaultPrevented = jQueryEvent.isDefaultPrevented();
|
||||
}
|
||||
const evt = hydrateObj(new Event(event, {
|
||||
bubbles,
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
}), args);
|
||||
if (defaultPrevented) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
if (nativeDispatch) {
|
||||
element.dispatchEvent(evt);
|
||||
}
|
||||
if (evt.defaultPrevented && jQueryEvent) {
|
||||
jQueryEvent.preventDefault();
|
||||
}
|
||||
element.dispatchEvent(evt);
|
||||
return evt;
|
||||
}
|
||||
};
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
-20
@@ -301,20 +301,6 @@
|
||||
// allow cycling to get the last item in case key equals ARROW_UP_KEY
|
||||
index_js.getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Dropdown.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
static clearMenus(event) {
|
||||
if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY) {
|
||||
return;
|
||||
@@ -390,12 +376,6 @@
|
||||
Dropdown.getOrCreateInstance(this).toggle();
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Dropdown);
|
||||
|
||||
return Dropdown;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
-20
@@ -261,20 +261,6 @@
|
||||
this._element.style.paddingLeft = '';
|
||||
this._element.style.paddingRight = '';
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config, relatedTarget) {
|
||||
return this.each(function () {
|
||||
const data = Modal.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](relatedTarget);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -308,12 +294,6 @@
|
||||
});
|
||||
componentFunctions_js.enableDismissTrigger(Modal);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Modal);
|
||||
|
||||
return Modal;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
-20
@@ -177,20 +177,6 @@
|
||||
EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
|
||||
});
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Offcanvas.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,12 +220,6 @@
|
||||
});
|
||||
componentFunctions_js.enableDismissTrigger(Offcanvas);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Offcanvas);
|
||||
|
||||
return Offcanvas;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+4
-24
@@ -4,10 +4,10 @@
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./tooltip.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./tooltip', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Popover = factory(global.Tooltip, global.Index));
|
||||
})(this, (function (Tooltip, index_js) { 'use strict';
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./tooltip.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./tooltip'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Popover = factory(global.Tooltip));
|
||||
})(this, (function (Tooltip) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
@@ -68,28 +68,8 @@
|
||||
_getContent() {
|
||||
return this._resolvePossibleFunction(this._config.content);
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Popover.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Popover);
|
||||
|
||||
return Popover;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"popover.js","sources":["../src/popover.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Tooltip from './tooltip.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'popover'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Default = {\n ...Tooltip.Default,\n content: '',\n offset: [0, 8],\n placement: 'right',\n template: '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"popover-arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div>' +\n '</div>',\n trigger: 'click'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(null|string|element|function)'\n}\n\n/**\n * Class definition\n */\n\nclass Popover extends Tooltip {\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Overrides\n _isWithContent() {\n return this._getTitle() || this._getContent()\n }\n\n // Private\n _getContentForTemplate() {\n return {\n [SELECTOR_TITLE]: this._getTitle(),\n [SELECTOR_CONTENT]: this._getContent()\n }\n }\n\n _getContent() {\n return this._resolvePossibleFunction(this._config.content)\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Popover.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n })\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Popover)\n\nexport default Popover\n"],"names":["NAME","SELECTOR_TITLE","SELECTOR_CONTENT","Default","Tooltip","content","offset","placement","template","trigger","DefaultType","Popover","_isWithContent","_getTitle","_getContent","_getContentForTemplate","_resolvePossibleFunction","_config","jQueryInterface","config","each","data","getOrCreateInstance","TypeError","defineJQueryPlugin"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAKA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,SAAS;EAEtB,MAAMC,cAAc,GAAG,iBAAiB;EACxC,MAAMC,gBAAgB,GAAG,eAAe;EAExC,MAAMC,OAAO,GAAG;IACd,GAAGC,OAAO,CAACD,OAAO;EAClBE,EAAAA,OAAO,EAAE,EAAE;EACXC,EAAAA,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;EACdC,EAAAA,SAAS,EAAE,OAAO;IAClBC,QAAQ,EAAE,sCAAsC,GAC9C,mCAAmC,GACnC,kCAAkC,GAClC,kCAAkC,GAClC,QAAQ;EACVC,EAAAA,OAAO,EAAE;EACX,CAAC;EAED,MAAMC,WAAW,GAAG;IAClB,GAAGN,OAAO,CAACM,WAAW;EACtBL,EAAAA,OAAO,EAAE;EACX,CAAC;;EAED;EACA;EACA;;EAEA,MAAMM,OAAO,SAASP,OAAO,CAAC;EAC5B;IACA,WAAWD,OAAOA,GAAG;EACnB,IAAA,OAAOA,OAAO;EAChB,EAAA;IAEA,WAAWO,WAAWA,GAAG;EACvB,IAAA,OAAOA,WAAW;EACpB,EAAA;IAEA,WAAWV,IAAIA,GAAG;EAChB,IAAA,OAAOA,IAAI;EACb,EAAA;;EAEA;EACAY,EAAAA,cAAcA,GAAG;MACf,OAAO,IAAI,CAACC,SAAS,EAAE,IAAI,IAAI,CAACC,WAAW,EAAE;EAC/C,EAAA;;EAEA;EACAC,EAAAA,sBAAsBA,GAAG;MACvB,OAAO;EACL,MAAA,CAACd,cAAc,GAAG,IAAI,CAACY,SAAS,EAAE;EAClC,MAAA,CAACX,gBAAgB,GAAG,IAAI,CAACY,WAAW;OACrC;EACH,EAAA;EAEAA,EAAAA,WAAWA,GAAG;MACZ,OAAO,IAAI,CAACE,wBAAwB,CAAC,IAAI,CAACC,OAAO,CAACZ,OAAO,CAAC;EAC5D,EAAA;;EAEA;IACA,OAAOa,eAAeA,CAACC,MAAM,EAAE;EAC7B,IAAA,OAAO,IAAI,CAACC,IAAI,CAAC,YAAY;QAC3B,MAAMC,IAAI,GAAGV,OAAO,CAACW,mBAAmB,CAAC,IAAI,EAAEH,MAAM,CAAC;EAEtD,MAAA,IAAI,OAAOA,MAAM,KAAK,QAAQ,EAAE;EAC9B,QAAA;EACF,MAAA;EAEA,MAAA,IAAI,OAAOE,IAAI,CAACF,MAAM,CAAC,KAAK,WAAW,EAAE;EACvC,QAAA,MAAM,IAAII,SAAS,CAAC,CAAA,iBAAA,EAAoBJ,MAAM,GAAG,CAAC;EACpD,MAAA;EAEAE,MAAAA,IAAI,CAACF,MAAM,CAAC,EAAE;EAChB,IAAA,CAAC,CAAC;EACJ,EAAA;EACF;;EAEA;EACA;EACA;;AAEAK,6BAAkB,CAACb,OAAO,CAAC;;;;;;;;"}
|
||||
{"version":3,"file":"popover.js","sources":["../src/popover.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Tooltip from './tooltip.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'popover'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Default = {\n ...Tooltip.Default,\n content: '',\n offset: [0, 8],\n placement: 'right',\n template: '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"popover-arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div>' +\n '</div>',\n trigger: 'click'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(null|string|element|function)'\n}\n\n/**\n * Class definition\n */\n\nclass Popover extends Tooltip {\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Overrides\n _isWithContent() {\n return this._getTitle() || this._getContent()\n }\n\n // Private\n _getContentForTemplate() {\n return {\n [SELECTOR_TITLE]: this._getTitle(),\n [SELECTOR_CONTENT]: this._getContent()\n }\n }\n\n _getContent() {\n return this._resolvePossibleFunction(this._config.content)\n }\n}\n\nexport default Popover\n"],"names":["NAME","SELECTOR_TITLE","SELECTOR_CONTENT","Default","Tooltip","content","offset","placement","template","trigger","DefaultType","Popover","_isWithContent","_getTitle","_getContent","_getContentForTemplate","_resolvePossibleFunction","_config"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAIA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,SAAS;EAEtB,MAAMC,cAAc,GAAG,iBAAiB;EACxC,MAAMC,gBAAgB,GAAG,eAAe;EAExC,MAAMC,OAAO,GAAG;IACd,GAAGC,OAAO,CAACD,OAAO;EAClBE,EAAAA,OAAO,EAAE,EAAE;EACXC,EAAAA,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;EACdC,EAAAA,SAAS,EAAE,OAAO;IAClBC,QAAQ,EAAE,sCAAsC,GAC9C,mCAAmC,GACnC,kCAAkC,GAClC,kCAAkC,GAClC,QAAQ;EACVC,EAAAA,OAAO,EAAE;EACX,CAAC;EAED,MAAMC,WAAW,GAAG;IAClB,GAAGN,OAAO,CAACM,WAAW;EACtBL,EAAAA,OAAO,EAAE;EACX,CAAC;;EAED;EACA;EACA;;EAEA,MAAMM,OAAO,SAASP,OAAO,CAAC;EAC5B;IACA,WAAWD,OAAOA,GAAG;EACnB,IAAA,OAAOA,OAAO;EAChB,EAAA;IAEA,WAAWO,WAAWA,GAAG;EACvB,IAAA,OAAOA,WAAW;EACpB,EAAA;IAEA,WAAWV,IAAIA,GAAG;EAChB,IAAA,OAAOA,IAAI;EACb,EAAA;;EAEA;EACAY,EAAAA,cAAcA,GAAG;MACf,OAAO,IAAI,CAACC,SAAS,EAAE,IAAI,IAAI,CAACC,WAAW,EAAE;EAC/C,EAAA;;EAEA;EACAC,EAAAA,sBAAsBA,GAAG;MACvB,OAAO;EACL,MAAA,CAACd,cAAc,GAAG,IAAI,CAACY,SAAS,EAAE;EAClC,MAAA,CAACX,gBAAgB,GAAG,IAAI,CAACY,WAAW;OACrC;EACH,EAAA;EAEAA,EAAAA,WAAWA,GAAG;MACZ,OAAO,IAAI,CAACE,wBAAwB,CAAC,IAAI,CAACC,OAAO,CAACZ,OAAO,CAAC;EAC5D,EAAA;EACF;;;;;;;;"}
|
||||
Vendored
-20
@@ -237,20 +237,6 @@
|
||||
node.classList.remove(CLASS_NAME_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = ScrollSpy.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,12 +249,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(ScrollSpy);
|
||||
|
||||
return ScrollSpy;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
-19
@@ -235,20 +235,6 @@
|
||||
_getOuterElement(elem) {
|
||||
return elem.closest(SELECTOR_OUTER) || elem;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Tab.getOrCreateInstance(this);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,11 +259,6 @@
|
||||
Tab.getOrCreateInstance(element);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Tab);
|
||||
|
||||
return Tab;
|
||||
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
-19
@@ -165,19 +165,6 @@
|
||||
clearTimeout(this._timeout);
|
||||
this._timeout = null;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Toast.getOrCreateInstance(this, config);
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,12 +173,6 @@
|
||||
|
||||
componentFunctions_js.enableDismissTrigger(Toast);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Toast);
|
||||
|
||||
return Toast;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
-20
@@ -518,28 +518,8 @@
|
||||
this.tip = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Tooltip.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Tooltip);
|
||||
|
||||
return Tooltip;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-29
@@ -81,15 +81,11 @@
|
||||
if (!object || typeof object !== 'object') {
|
||||
return false;
|
||||
}
|
||||
if (typeof object.jquery !== 'undefined') {
|
||||
object = object[0];
|
||||
}
|
||||
return typeof object.nodeType !== 'undefined';
|
||||
};
|
||||
const getElement = object => {
|
||||
// it's a jQuery object or a node element
|
||||
if (isElement(object)) {
|
||||
return object.jquery ? object[0] : object;
|
||||
return object;
|
||||
}
|
||||
if (typeof object === 'string' && object.length > 0) {
|
||||
return document.querySelector(parseSelector(object));
|
||||
@@ -162,12 +158,6 @@
|
||||
const reflow = element => {
|
||||
element.offsetHeight; // eslint-disable-line no-unused-expressions
|
||||
};
|
||||
const getjQuery = () => {
|
||||
if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return window.jQuery;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
@@ -185,22 +175,6 @@
|
||||
}
|
||||
};
|
||||
const isRTL = () => document.documentElement.dir === 'rtl';
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
|
||||
return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue;
|
||||
};
|
||||
@@ -255,7 +229,6 @@
|
||||
return list[Math.max(0, Math.min(index, listLength - 1))];
|
||||
};
|
||||
|
||||
exports.defineJQueryPlugin = defineJQueryPlugin;
|
||||
exports.execute = execute;
|
||||
exports.executeAfterTransition = executeAfterTransition;
|
||||
exports.findShadowRoot = findShadowRoot;
|
||||
@@ -263,7 +236,6 @@
|
||||
exports.getNextActiveElement = getNextActiveElement;
|
||||
exports.getTransitionDurationFromElement = getTransitionDurationFromElement;
|
||||
exports.getUID = getUID;
|
||||
exports.getjQuery = getjQuery;
|
||||
exports.isDisabled = isDisabled;
|
||||
exports.isElement = isElement;
|
||||
exports.isRTL = isRTL;
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -8,7 +8,6 @@
|
||||
import BaseComponent from './base-component.js'
|
||||
import EventHandler from './dom/event-handler.js'
|
||||
import { enableDismissTrigger } from './util/component-functions.js'
|
||||
import { defineJQueryPlugin } from './util/index.js'
|
||||
|
||||
/**
|
||||
* Constants
|
||||
@@ -53,23 +52,6 @@ class Alert extends BaseComponent {
|
||||
EventHandler.trigger(this._element, EVENT_CLOSED)
|
||||
this.dispose()
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Alert.getOrCreateInstance(this)
|
||||
|
||||
if (typeof config !== 'string') {
|
||||
return
|
||||
}
|
||||
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`)
|
||||
}
|
||||
|
||||
data[config](this)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,10 +60,4 @@ class Alert extends BaseComponent {
|
||||
|
||||
enableDismissTrigger(Alert, 'close')
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Alert)
|
||||
|
||||
export default Alert
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
import BaseComponent from './base-component.js'
|
||||
import EventHandler from './dom/event-handler.js'
|
||||
import { defineJQueryPlugin } from './util/index.js'
|
||||
|
||||
/**
|
||||
* Constants
|
||||
@@ -37,17 +36,6 @@ class Button extends BaseComponent {
|
||||
// Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
|
||||
this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE))
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Button.getOrCreateInstance(this)
|
||||
|
||||
if (config === 'toggle') {
|
||||
data[config]()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,10 +51,4 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {
|
||||
data.toggle()
|
||||
})
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Button)
|
||||
|
||||
export default Button
|
||||
|
||||
@@ -10,7 +10,6 @@ import EventHandler from './dom/event-handler.js'
|
||||
import Manipulator from './dom/manipulator.js'
|
||||
import SelectorEngine from './dom/selector-engine.js'
|
||||
import {
|
||||
defineJQueryPlugin,
|
||||
getNextActiveElement,
|
||||
isRTL,
|
||||
isVisible,
|
||||
@@ -403,26 +402,6 @@ class Carousel extends BaseComponent {
|
||||
|
||||
return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Carousel.getOrCreateInstance(this, config)
|
||||
|
||||
if (typeof config === 'number') {
|
||||
data.to(config)
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof config === 'string') {
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`)
|
||||
}
|
||||
|
||||
data[config]()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -465,10 +444,4 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Carousel)
|
||||
|
||||
export default Carousel
|
||||
|
||||
@@ -9,7 +9,6 @@ import BaseComponent from './base-component.js'
|
||||
import EventHandler from './dom/event-handler.js'
|
||||
import SelectorEngine from './dom/selector-engine.js'
|
||||
import {
|
||||
defineJQueryPlugin,
|
||||
getElement,
|
||||
reflow
|
||||
} from './util/index.js'
|
||||
@@ -251,26 +250,6 @@ class Collapse extends BaseComponent {
|
||||
element.setAttribute('aria-expanded', isOpen)
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
const _config = {}
|
||||
if (typeof config === 'string' && /show|hide/.test(config)) {
|
||||
_config.toggle = false
|
||||
}
|
||||
|
||||
return this.each(function () {
|
||||
const data = Collapse.getOrCreateInstance(this, _config)
|
||||
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`)
|
||||
}
|
||||
|
||||
data[config]()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,10 +267,4 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Collapse)
|
||||
|
||||
export default Collapse
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
import { getjQuery } from '../util/index.js'
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
@@ -261,38 +259,8 @@ const EventHandler = {
|
||||
return null
|
||||
}
|
||||
|
||||
const $ = getjQuery()
|
||||
const typeEvent = getTypeEvent(event)
|
||||
const inNamespace = event !== typeEvent
|
||||
|
||||
let jQueryEvent = null
|
||||
let bubbles = true
|
||||
let nativeDispatch = true
|
||||
let defaultPrevented = false
|
||||
|
||||
if (inNamespace && $) {
|
||||
jQueryEvent = $.Event(event, args)
|
||||
|
||||
$(element).trigger(jQueryEvent)
|
||||
bubbles = !jQueryEvent.isPropagationStopped()
|
||||
nativeDispatch = !jQueryEvent.isImmediatePropagationStopped()
|
||||
defaultPrevented = jQueryEvent.isDefaultPrevented()
|
||||
}
|
||||
|
||||
const evt = hydrateObj(new Event(event, { bubbles, cancelable: true }), args)
|
||||
|
||||
if (defaultPrevented) {
|
||||
evt.preventDefault()
|
||||
}
|
||||
|
||||
if (nativeDispatch) {
|
||||
element.dispatchEvent(evt)
|
||||
}
|
||||
|
||||
if (evt.defaultPrevented && jQueryEvent) {
|
||||
jQueryEvent.preventDefault()
|
||||
}
|
||||
|
||||
const evt = hydrateObj(new Event(event, { bubbles: true, cancelable: true }), args)
|
||||
element.dispatchEvent(evt)
|
||||
return evt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import EventHandler from './dom/event-handler.js'
|
||||
import Manipulator from './dom/manipulator.js'
|
||||
import SelectorEngine from './dom/selector-engine.js'
|
||||
import {
|
||||
defineJQueryPlugin,
|
||||
execute,
|
||||
getElement,
|
||||
getNextActiveElement,
|
||||
@@ -336,23 +335,6 @@ class Dropdown extends BaseComponent {
|
||||
getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus()
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Dropdown.getOrCreateInstance(this, config)
|
||||
|
||||
if (typeof config !== 'string') {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`)
|
||||
}
|
||||
|
||||
data[config]()
|
||||
})
|
||||
}
|
||||
|
||||
static clearMenus(event) {
|
||||
if (event.button === RIGHT_MOUSE_BUTTON || (event.type === 'keyup' && event.key !== TAB_KEY)) {
|
||||
return
|
||||
@@ -446,10 +428,4 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
|
||||
Dropdown.getOrCreateInstance(this).toggle()
|
||||
})
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Dropdown)
|
||||
|
||||
export default Dropdown
|
||||
|
||||
+1
-24
@@ -12,7 +12,7 @@ import Backdrop from './util/backdrop.js'
|
||||
import { enableDismissTrigger } from './util/component-functions.js'
|
||||
import FocusTrap from './util/focustrap.js'
|
||||
import {
|
||||
defineJQueryPlugin, isRTL, isVisible, reflow
|
||||
isRTL, isVisible, reflow
|
||||
} from './util/index.js'
|
||||
import ScrollBarHelper from './util/scrollbar.js'
|
||||
|
||||
@@ -313,23 +313,6 @@ class Modal extends BaseComponent {
|
||||
this._element.style.paddingLeft = ''
|
||||
this._element.style.paddingRight = ''
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config, relatedTarget) {
|
||||
return this.each(function () {
|
||||
const data = Modal.getOrCreateInstance(this, config)
|
||||
|
||||
if (typeof config !== 'string') {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`)
|
||||
}
|
||||
|
||||
data[config](relatedTarget)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,10 +352,4 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
|
||||
|
||||
enableDismissTrigger(Modal)
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Modal)
|
||||
|
||||
export default Modal
|
||||
|
||||
@@ -12,7 +12,6 @@ import Backdrop from './util/backdrop.js'
|
||||
import { enableDismissTrigger } from './util/component-functions.js'
|
||||
import FocusTrap from './util/focustrap.js'
|
||||
import {
|
||||
defineJQueryPlugin,
|
||||
isDisabled,
|
||||
isVisible
|
||||
} from './util/index.js'
|
||||
@@ -206,23 +205,6 @@ class Offcanvas extends BaseComponent {
|
||||
EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)
|
||||
})
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Offcanvas.getOrCreateInstance(this, config)
|
||||
|
||||
if (typeof config !== 'string') {
|
||||
return
|
||||
}
|
||||
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`)
|
||||
}
|
||||
|
||||
data[config](this)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,10 +255,4 @@ EventHandler.on(window, EVENT_RESIZE, () => {
|
||||
|
||||
enableDismissTrigger(Offcanvas)
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Offcanvas)
|
||||
|
||||
export default Offcanvas
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
import Tooltip from './tooltip.js'
|
||||
import { defineJQueryPlugin } from './util/index.js'
|
||||
|
||||
/**
|
||||
* Constants
|
||||
@@ -69,29 +68,6 @@ class Popover extends Tooltip {
|
||||
_getContent() {
|
||||
return this._resolvePossibleFunction(this._config.content)
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Popover.getOrCreateInstance(this, config)
|
||||
|
||||
if (typeof config !== 'string') {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`)
|
||||
}
|
||||
|
||||
data[config]()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Popover)
|
||||
|
||||
export default Popover
|
||||
|
||||
+1
-24
@@ -9,7 +9,7 @@ import BaseComponent from './base-component.js'
|
||||
import EventHandler from './dom/event-handler.js'
|
||||
import SelectorEngine from './dom/selector-engine.js'
|
||||
import {
|
||||
defineJQueryPlugin, getElement, isDisabled, isVisible
|
||||
getElement, isDisabled, isVisible
|
||||
} from './util/index.js'
|
||||
|
||||
/**
|
||||
@@ -258,23 +258,6 @@ class ScrollSpy extends BaseComponent {
|
||||
node.classList.remove(CLASS_NAME_ACTIVE)
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = ScrollSpy.getOrCreateInstance(this, config)
|
||||
|
||||
if (typeof config !== 'string') {
|
||||
return
|
||||
}
|
||||
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`)
|
||||
}
|
||||
|
||||
data[config]()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,10 +270,4 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(ScrollSpy)
|
||||
|
||||
export default ScrollSpy
|
||||
|
||||
+1
-23
@@ -8,7 +8,7 @@
|
||||
import BaseComponent from './base-component.js'
|
||||
import EventHandler from './dom/event-handler.js'
|
||||
import SelectorEngine from './dom/selector-engine.js'
|
||||
import { defineJQueryPlugin, getNextActiveElement, isDisabled } from './util/index.js'
|
||||
import { getNextActiveElement, isDisabled } from './util/index.js'
|
||||
|
||||
/**
|
||||
* Constants
|
||||
@@ -263,23 +263,6 @@ class Tab extends BaseComponent {
|
||||
_getOuterElement(elem) {
|
||||
return elem.closest(SELECTOR_OUTER) || elem
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Tab.getOrCreateInstance(this)
|
||||
|
||||
if (typeof config !== 'string') {
|
||||
return
|
||||
}
|
||||
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`)
|
||||
}
|
||||
|
||||
data[config]()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -306,10 +289,5 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
||||
Tab.getOrCreateInstance(element)
|
||||
}
|
||||
})
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Tab)
|
||||
|
||||
export default Tab
|
||||
|
||||
+1
-22
@@ -8,7 +8,7 @@
|
||||
import BaseComponent from './base-component.js'
|
||||
import EventHandler from './dom/event-handler.js'
|
||||
import { enableDismissTrigger } from './util/component-functions.js'
|
||||
import { defineJQueryPlugin, reflow } from './util/index.js'
|
||||
import { reflow } from './util/index.js'
|
||||
|
||||
/**
|
||||
* Constants
|
||||
@@ -192,21 +192,6 @@ class Toast extends BaseComponent {
|
||||
clearTimeout(this._timeout)
|
||||
this._timeout = null
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Toast.getOrCreateInstance(this, config)
|
||||
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`)
|
||||
}
|
||||
|
||||
data[config](this)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,10 +200,4 @@ class Toast extends BaseComponent {
|
||||
|
||||
enableDismissTrigger(Toast)
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Toast)
|
||||
|
||||
export default Toast
|
||||
|
||||
+1
-25
@@ -10,7 +10,7 @@ import BaseComponent from './base-component.js'
|
||||
import EventHandler from './dom/event-handler.js'
|
||||
import Manipulator from './dom/manipulator.js'
|
||||
import {
|
||||
defineJQueryPlugin, execute, findShadowRoot, getElement, getUID, isRTL, noop
|
||||
execute, findShadowRoot, getElement, getUID, isRTL, noop
|
||||
} from './util/index.js'
|
||||
import { DefaultAllowlist } from './util/sanitizer.js'
|
||||
import TemplateFactory from './util/template-factory.js'
|
||||
@@ -605,29 +605,5 @@ class Tooltip extends BaseComponent {
|
||||
this.tip = null
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Tooltip.getOrCreateInstance(this, config)
|
||||
|
||||
if (typeof config !== 'string') {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`)
|
||||
}
|
||||
|
||||
data[config]()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Tooltip)
|
||||
|
||||
export default Tooltip
|
||||
|
||||
+1
-33
@@ -76,17 +76,12 @@ const isElement = object => {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof object.jquery !== 'undefined') {
|
||||
object = object[0]
|
||||
}
|
||||
|
||||
return typeof object.nodeType !== 'undefined'
|
||||
}
|
||||
|
||||
const getElement = object => {
|
||||
// it's a jQuery object or a node element
|
||||
if (isElement(object)) {
|
||||
return object.jquery ? object[0] : object
|
||||
return object
|
||||
}
|
||||
|
||||
if (typeof object === 'string' && object.length > 0) {
|
||||
@@ -176,14 +171,6 @@ const reflow = element => {
|
||||
element.offsetHeight // eslint-disable-line no-unused-expressions
|
||||
}
|
||||
|
||||
const getjQuery = () => {
|
||||
if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return window.jQuery
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
const DOMContentLoadedCallbacks = []
|
||||
|
||||
const onDOMContentLoaded = callback => {
|
||||
@@ -205,23 +192,6 @@ const onDOMContentLoaded = callback => {
|
||||
|
||||
const isRTL = () => document.documentElement.dir === 'rtl'
|
||||
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery()
|
||||
/* istanbul ignore if */
|
||||
if ($) {
|
||||
const name = plugin.NAME
|
||||
const JQUERY_NO_CONFLICT = $.fn[name]
|
||||
$.fn[name] = plugin.jQueryInterface
|
||||
$.fn[name].Constructor = plugin
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT
|
||||
return plugin.jQueryInterface
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
|
||||
return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue
|
||||
}
|
||||
@@ -284,12 +254,10 @@ const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed
|
||||
}
|
||||
|
||||
export {
|
||||
defineJQueryPlugin,
|
||||
execute,
|
||||
executeAfterTransition,
|
||||
findShadowRoot,
|
||||
getElement,
|
||||
getjQuery,
|
||||
getNextActiveElement,
|
||||
getTransitionDurationFromElement,
|
||||
getUID,
|
||||
|
||||
@@ -27,16 +27,6 @@ export const createEvent = (eventName, parameters = {}) => {
|
||||
return new Event(eventName, parameters)
|
||||
}
|
||||
|
||||
export const jQueryMock = {
|
||||
elements: undefined,
|
||||
fn: {},
|
||||
each(fn) {
|
||||
for (const element of this.elements) {
|
||||
fn.call(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const clearBodyAndDocument = () => {
|
||||
const attributes = ['data-bs-padding-right', 'style']
|
||||
|
||||
|
||||
+1
-17
@@ -11,7 +11,6 @@ const { browsers } = require('./browsers.js')
|
||||
const ENV = process.env
|
||||
const BROWSERSTACK = Boolean(ENV.BROWSERSTACK)
|
||||
const DEBUG = Boolean(ENV.DEBUG)
|
||||
const JQUERY_TEST = Boolean(ENV.JQUERY)
|
||||
|
||||
const frameworks = [
|
||||
'jasmine'
|
||||
@@ -61,7 +60,7 @@ const config = {
|
||||
files: [
|
||||
'node_modules/hammer-simulator/index.js',
|
||||
{
|
||||
pattern: 'js/tests/unit/**/!(jquery).spec.js',
|
||||
pattern: 'js/tests/unit/**/*.spec.js',
|
||||
watched: !BROWSERSTACK
|
||||
}
|
||||
],
|
||||
@@ -111,21 +110,6 @@ if (BROWSERSTACK) {
|
||||
config.customLaunchers = browsers
|
||||
config.browsers = Object.keys(browsers)
|
||||
reporters.push('BrowserStack', 'kjhtml')
|
||||
} else if (JQUERY_TEST) {
|
||||
frameworks.push('detectBrowsers')
|
||||
plugins.push(
|
||||
'karma-chrome-launcher',
|
||||
'karma-firefox-launcher',
|
||||
'karma-detect-browsers'
|
||||
)
|
||||
config.detectBrowsers = detectBrowsers
|
||||
config.files = [
|
||||
'node_modules/jquery/dist/jquery.slim.min.js',
|
||||
{
|
||||
pattern: 'js/tests/unit/jquery.spec.js',
|
||||
watched: false
|
||||
}
|
||||
]
|
||||
} else {
|
||||
frameworks.push('detectBrowsers')
|
||||
plugins.push(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Alert from '../../src/alert.js'
|
||||
import { getTransitionDurationFromElement } from '../../src/util/index.js'
|
||||
import { clearFixture, getFixture, jQueryMock } from '../helpers/fixture.js'
|
||||
import { clearFixture, getFixture } from '../helpers/fixture.js'
|
||||
|
||||
describe('Alert', () => {
|
||||
let fixtureEl
|
||||
@@ -141,80 +141,6 @@ describe('Alert', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('jQueryInterface', () => {
|
||||
it('should handle config passed and toggle existing alert', () => {
|
||||
fixtureEl.innerHTML = '<div class="alert"></div>'
|
||||
|
||||
const alertEl = fixtureEl.querySelector('.alert')
|
||||
const alert = new Alert(alertEl)
|
||||
|
||||
const spy = spyOn(alert, 'close')
|
||||
|
||||
jQueryMock.fn.alert = Alert.jQueryInterface
|
||||
jQueryMock.elements = [alertEl]
|
||||
|
||||
jQueryMock.fn.alert.call(jQueryMock, 'close')
|
||||
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should create new alert instance and call close', () => {
|
||||
fixtureEl.innerHTML = '<div class="alert"></div>'
|
||||
|
||||
const alertEl = fixtureEl.querySelector('.alert')
|
||||
|
||||
jQueryMock.fn.alert = Alert.jQueryInterface
|
||||
jQueryMock.elements = [alertEl]
|
||||
|
||||
expect(Alert.getInstance(alertEl)).toBeNull()
|
||||
jQueryMock.fn.alert.call(jQueryMock, 'close')
|
||||
|
||||
expect(fixtureEl.querySelector('.alert')).toBeNull()
|
||||
})
|
||||
|
||||
it('should just create an alert instance without calling close', () => {
|
||||
fixtureEl.innerHTML = '<div class="alert"></div>'
|
||||
|
||||
const alertEl = fixtureEl.querySelector('.alert')
|
||||
|
||||
jQueryMock.fn.alert = Alert.jQueryInterface
|
||||
jQueryMock.elements = [alertEl]
|
||||
|
||||
jQueryMock.fn.alert.call(jQueryMock)
|
||||
|
||||
expect(Alert.getInstance(alertEl)).not.toBeNull()
|
||||
expect(fixtureEl.querySelector('.alert')).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should throw an error on undefined method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const action = 'undefinedMethod'
|
||||
|
||||
jQueryMock.fn.alert = Alert.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.alert.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
|
||||
it('should throw an error on protected method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const action = '_getConfig'
|
||||
|
||||
jQueryMock.fn.alert = Alert.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.alert.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getInstance', () => {
|
||||
it('should return alert instance', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
@@ -124,18 +124,11 @@ describe('Base Component', () => {
|
||||
expect(DummyClass.getInstance(element)).toBeInstanceOf(DummyClass)
|
||||
})
|
||||
|
||||
it('should accept element, either passed as a CSS selector, jQuery element, or DOM element', () => {
|
||||
it('should accept element, either passed as a CSS selector or DOM element', () => {
|
||||
createInstance()
|
||||
|
||||
expect(DummyClass.getInstance('#foo')).toEqual(instance)
|
||||
expect(DummyClass.getInstance(element)).toEqual(instance)
|
||||
|
||||
const fakejQueryObject = {
|
||||
0: element,
|
||||
jquery: 'foo'
|
||||
}
|
||||
|
||||
expect(DummyClass.getInstance(fakejQueryObject)).toEqual(instance)
|
||||
})
|
||||
|
||||
it('should return null when there is no instance', () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Button from '../../src/button.js'
|
||||
import { clearFixture, getFixture, jQueryMock } from '../helpers/fixture.js'
|
||||
import { clearFixture, getFixture } from '../helpers/fixture.js'
|
||||
|
||||
describe('Button', () => {
|
||||
let fixtureEl
|
||||
@@ -93,52 +93,6 @@ describe('Button', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('jQueryInterface', () => {
|
||||
it('should handle config passed and toggle existing button', () => {
|
||||
fixtureEl.innerHTML = '<button class="btn" data-bs-toggle="button"></button>'
|
||||
|
||||
const btnEl = fixtureEl.querySelector('.btn')
|
||||
const button = new Button(btnEl)
|
||||
|
||||
const spy = spyOn(button, 'toggle')
|
||||
|
||||
jQueryMock.fn.button = Button.jQueryInterface
|
||||
jQueryMock.elements = [btnEl]
|
||||
|
||||
jQueryMock.fn.button.call(jQueryMock, 'toggle')
|
||||
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should create new button instance and call toggle', () => {
|
||||
fixtureEl.innerHTML = '<button class="btn" data-bs-toggle="button"></button>'
|
||||
|
||||
const btnEl = fixtureEl.querySelector('.btn')
|
||||
|
||||
jQueryMock.fn.button = Button.jQueryInterface
|
||||
jQueryMock.elements = [btnEl]
|
||||
|
||||
jQueryMock.fn.button.call(jQueryMock, 'toggle')
|
||||
|
||||
expect(Button.getInstance(btnEl)).not.toBeNull()
|
||||
expect(btnEl).toHaveClass('active')
|
||||
})
|
||||
|
||||
it('should just create a button instance without calling toggle', () => {
|
||||
fixtureEl.innerHTML = '<button class="btn" data-bs-toggle="button"></button>'
|
||||
|
||||
const btnEl = fixtureEl.querySelector('.btn')
|
||||
|
||||
jQueryMock.fn.button = Button.jQueryInterface
|
||||
jQueryMock.elements = [btnEl]
|
||||
|
||||
jQueryMock.fn.button.call(jQueryMock)
|
||||
|
||||
expect(Button.getInstance(btnEl)).not.toBeNull()
|
||||
expect(btnEl).not.toHaveClass('active')
|
||||
})
|
||||
})
|
||||
|
||||
describe('getInstance', () => {
|
||||
it('should return button instance', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
@@ -3,7 +3,7 @@ import EventHandler from '../../src/dom/event-handler.js'
|
||||
import { isRTL, noop } from '../../src/util/index.js'
|
||||
import Swipe from '../../src/util/swipe.js'
|
||||
import {
|
||||
clearFixture, createEvent, getFixture, jQueryMock
|
||||
clearFixture, createEvent, getFixture
|
||||
} from '../helpers/fixture.js'
|
||||
|
||||
describe('Carousel', () => {
|
||||
@@ -1379,66 +1379,6 @@ describe('Carousel', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('jQueryInterface', () => {
|
||||
it('should create a carousel', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
jQueryMock.fn.carousel = Carousel.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.carousel.call(jQueryMock)
|
||||
|
||||
expect(Carousel.getInstance(div)).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should not re create a carousel', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const carousel = new Carousel(div)
|
||||
|
||||
jQueryMock.fn.carousel = Carousel.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.carousel.call(jQueryMock)
|
||||
|
||||
expect(Carousel.getInstance(div)).toEqual(carousel)
|
||||
})
|
||||
|
||||
it('should call to if the config is a number', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const carousel = new Carousel(div)
|
||||
const slideTo = 2
|
||||
|
||||
const spy = spyOn(carousel, 'to')
|
||||
|
||||
jQueryMock.fn.carousel = Carousel.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.carousel.call(jQueryMock, slideTo)
|
||||
|
||||
expect(spy).toHaveBeenCalledWith(slideTo)
|
||||
})
|
||||
|
||||
it('should throw error on undefined method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const action = 'undefinedMethod'
|
||||
|
||||
jQueryMock.fn.carousel = Carousel.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.carousel.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('data-api', () => {
|
||||
it('should init carousels with data-bs-ride="carousel" on load', () => {
|
||||
fixtureEl.innerHTML = '<div data-bs-ride="carousel"></div>'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Collapse from '../../src/collapse.js'
|
||||
import EventHandler from '../../src/dom/event-handler.js'
|
||||
import { clearFixture, getFixture, jQueryMock } from '../helpers/fixture.js'
|
||||
import { clearFixture, getFixture } from '../helpers/fixture.js'
|
||||
|
||||
describe('Collapse', () => {
|
||||
let fixtureEl
|
||||
@@ -43,30 +43,7 @@ describe('Collapse', () => {
|
||||
expect(collapseByElement._element).toEqual(collapseEl)
|
||||
})
|
||||
|
||||
it('should allow jquery object in parent config', () => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<div class="my-collapse">',
|
||||
' <div class="item">',
|
||||
' <a data-bs-toggle="collapse" href="#">Toggle item</a>',
|
||||
' <div class="collapse">Lorem ipsum</div>',
|
||||
' </div>',
|
||||
'</div>'
|
||||
].join('')
|
||||
|
||||
const collapseEl = fixtureEl.querySelector('div.collapse')
|
||||
const myCollapseEl = fixtureEl.querySelector('.my-collapse')
|
||||
const fakejQueryObject = {
|
||||
0: myCollapseEl,
|
||||
jquery: 'foo'
|
||||
}
|
||||
const collapse = new Collapse(collapseEl, {
|
||||
parent: fakejQueryObject
|
||||
})
|
||||
|
||||
expect(collapse._config.parent).toEqual(myCollapseEl)
|
||||
})
|
||||
|
||||
it('should allow non jquery object in parent config', () => {
|
||||
it('should allow object in parent config', () => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<div class="my-collapse">',
|
||||
' <div class="item">',
|
||||
@@ -943,49 +920,6 @@ describe('Collapse', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('jQueryInterface', () => {
|
||||
it('should create a collapse', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
jQueryMock.fn.collapse = Collapse.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.collapse.call(jQueryMock)
|
||||
|
||||
expect(Collapse.getInstance(div)).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should not re create a collapse', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const collapse = new Collapse(div)
|
||||
|
||||
jQueryMock.fn.collapse = Collapse.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.collapse.call(jQueryMock)
|
||||
|
||||
expect(Collapse.getInstance(div)).toEqual(collapse)
|
||||
})
|
||||
|
||||
it('should throw error on undefined method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const action = 'undefinedMethod'
|
||||
|
||||
jQueryMock.fn.collapse = Collapse.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.collapse.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getInstance', () => {
|
||||
it('should return collapse instance', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
@@ -2,7 +2,7 @@ import EventHandler from '../../src/dom/event-handler.js'
|
||||
import Dropdown from '../../src/dropdown.js'
|
||||
import { noop } from '../../src/util/index.js'
|
||||
import {
|
||||
clearFixture, createEvent, getFixture, jQueryMock
|
||||
clearFixture, createEvent, getFixture
|
||||
} from '../helpers/fixture.js'
|
||||
|
||||
describe('Dropdown', () => {
|
||||
@@ -508,32 +508,6 @@ describe('Dropdown', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('should toggle a dropdown with a jquery object reference', () => {
|
||||
return new Promise(resolve => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<div class="dropdown">',
|
||||
' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
|
||||
' <div class="dropdown-menu">',
|
||||
' <a class="dropdown-item" href="#">Secondary link</a>',
|
||||
' </div>',
|
||||
'</div>'
|
||||
].join('')
|
||||
|
||||
const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
|
||||
const dropdown = new Dropdown(btnDropdown, {
|
||||
reference: { 0: fixtureEl, jquery: 'jQuery' }
|
||||
})
|
||||
|
||||
btnDropdown.addEventListener('shown.bs.dropdown', () => {
|
||||
expect(btnDropdown).toHaveClass('show')
|
||||
expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
|
||||
resolve()
|
||||
})
|
||||
|
||||
dropdown.toggle()
|
||||
})
|
||||
})
|
||||
|
||||
it('should toggle a dropdown with a valid virtual element reference', () => {
|
||||
return new Promise(resolve => {
|
||||
fixtureEl.innerHTML = [
|
||||
@@ -2218,49 +2192,6 @@ describe('Dropdown', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('jQueryInterface', () => {
|
||||
it('should create a dropdown', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
jQueryMock.fn.dropdown = Dropdown.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.dropdown.call(jQueryMock)
|
||||
|
||||
expect(Dropdown.getInstance(div)).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should not re create a dropdown', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const dropdown = new Dropdown(div)
|
||||
|
||||
jQueryMock.fn.dropdown = Dropdown.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.dropdown.call(jQueryMock)
|
||||
|
||||
expect(Dropdown.getInstance(div)).toEqual(dropdown)
|
||||
})
|
||||
|
||||
it('should throw error on undefined method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const action = 'undefinedMethod'
|
||||
|
||||
jQueryMock.fn.dropdown = Dropdown.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.dropdown.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getInstance', () => {
|
||||
it('should return dropdown instance', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/* eslint-env jquery */
|
||||
|
||||
import Alert from '../../src/alert.js'
|
||||
import Button from '../../src/button.js'
|
||||
import Carousel from '../../src/carousel.js'
|
||||
import Collapse from '../../src/collapse.js'
|
||||
import Dropdown from '../../src/dropdown.js'
|
||||
import Modal from '../../src/modal.js'
|
||||
import Offcanvas from '../../src/offcanvas.js'
|
||||
import Popover from '../../src/popover.js'
|
||||
import ScrollSpy from '../../src/scrollspy.js'
|
||||
import Tab from '../../src/tab.js'
|
||||
import Toast from '../../src/toast.js'
|
||||
import Tooltip from '../../src/tooltip.js'
|
||||
import { clearFixture, getFixture } from '../helpers/fixture.js'
|
||||
|
||||
describe('jQuery', () => {
|
||||
let fixtureEl
|
||||
|
||||
beforeAll(() => {
|
||||
fixtureEl = getFixture()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
clearFixture()
|
||||
})
|
||||
|
||||
it('should add all plugins in jQuery', () => {
|
||||
expect(Alert.jQueryInterface).toEqual(jQuery.fn.alert)
|
||||
expect(Button.jQueryInterface).toEqual(jQuery.fn.button)
|
||||
expect(Carousel.jQueryInterface).toEqual(jQuery.fn.carousel)
|
||||
expect(Collapse.jQueryInterface).toEqual(jQuery.fn.collapse)
|
||||
expect(Dropdown.jQueryInterface).toEqual(jQuery.fn.dropdown)
|
||||
expect(Modal.jQueryInterface).toEqual(jQuery.fn.modal)
|
||||
expect(Offcanvas.jQueryInterface).toEqual(jQuery.fn.offcanvas)
|
||||
expect(Popover.jQueryInterface).toEqual(jQuery.fn.popover)
|
||||
expect(ScrollSpy.jQueryInterface).toEqual(jQuery.fn.scrollspy)
|
||||
expect(Tab.jQueryInterface).toEqual(jQuery.fn.tab)
|
||||
expect(Toast.jQueryInterface).toEqual(jQuery.fn.toast)
|
||||
expect(Tooltip.jQueryInterface).toEqual(jQuery.fn.tooltip)
|
||||
})
|
||||
|
||||
it('should use jQuery event system', () => {
|
||||
return new Promise(resolve => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<div class="alert">',
|
||||
' <button type="button" data-bs-dismiss="alert">x</button>',
|
||||
'</div>'
|
||||
].join('')
|
||||
|
||||
$(fixtureEl).find('.alert')
|
||||
.one('closed.bs.alert', () => {
|
||||
expect($(fixtureEl).find('.alert')).toHaveSize(0)
|
||||
resolve()
|
||||
})
|
||||
|
||||
$(fixtureEl).find('button').trigger('click')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -2,7 +2,7 @@ import EventHandler from '../../src/dom/event-handler.js'
|
||||
import Modal from '../../src/modal.js'
|
||||
import ScrollBarHelper from '../../src/util/scrollbar.js'
|
||||
import {
|
||||
clearBodyAndDocument, clearFixture, createEvent, getFixture, jQueryMock
|
||||
clearBodyAndDocument, clearFixture, createEvent, getFixture
|
||||
} from '../helpers/fixture.js'
|
||||
|
||||
describe('Modal', () => {
|
||||
@@ -1162,96 +1162,6 @@ describe('Modal', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('jQueryInterface', () => {
|
||||
it('should create a modal', () => {
|
||||
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
jQueryMock.fn.modal = Modal.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.modal.call(jQueryMock)
|
||||
|
||||
expect(Modal.getInstance(div)).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should create a modal with given config', () => {
|
||||
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
jQueryMock.fn.modal = Modal.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.modal.call(jQueryMock, { keyboard: false })
|
||||
const spy = spyOn(Modal.prototype, 'constructor')
|
||||
expect(spy).not.toHaveBeenCalledWith(div, { keyboard: false })
|
||||
|
||||
const modal = Modal.getInstance(div)
|
||||
expect(modal).not.toBeNull()
|
||||
expect(modal._config.keyboard).toBeFalse()
|
||||
})
|
||||
|
||||
it('should not re create a modal', () => {
|
||||
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const modal = new Modal(div)
|
||||
|
||||
jQueryMock.fn.modal = Modal.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.modal.call(jQueryMock)
|
||||
|
||||
expect(Modal.getInstance(div)).toEqual(modal)
|
||||
})
|
||||
|
||||
it('should throw error on undefined method', () => {
|
||||
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const action = 'undefinedMethod'
|
||||
|
||||
jQueryMock.fn.modal = Modal.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.modal.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
|
||||
it('should call show method', () => {
|
||||
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const modal = new Modal(div)
|
||||
|
||||
jQueryMock.fn.modal = Modal.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
const spy = spyOn(modal, 'show')
|
||||
|
||||
jQueryMock.fn.modal.call(jQueryMock, 'show')
|
||||
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not call show method', () => {
|
||||
fixtureEl.innerHTML = '<div class="modal" data-bs-show="false"><div class="modal-dialog"></div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
jQueryMock.fn.modal = Modal.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
const spy = spyOn(Modal.prototype, 'show')
|
||||
|
||||
jQueryMock.fn.modal.call(jQueryMock)
|
||||
|
||||
expect(spy).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('getInstance', () => {
|
||||
it('should return modal instance', () => {
|
||||
|
||||
@@ -3,7 +3,7 @@ import Offcanvas from '../../src/offcanvas.js'
|
||||
import { isVisible } from '../../src/util/index.js'
|
||||
import ScrollBarHelper from '../../src/util/scrollbar.js'
|
||||
import {
|
||||
clearBodyAndDocument, clearFixture, createEvent, getFixture, jQueryMock
|
||||
clearBodyAndDocument, clearFixture, createEvent, getFixture
|
||||
} from '../helpers/fixture.js'
|
||||
|
||||
describe('Offcanvas', () => {
|
||||
@@ -738,106 +738,6 @@ describe('Offcanvas', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('jQueryInterface', () => {
|
||||
it('should create an offcanvas', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
jQueryMock.fn.offcanvas = Offcanvas.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.offcanvas.call(jQueryMock)
|
||||
|
||||
expect(Offcanvas.getInstance(div)).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should not re create an offcanvas', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const offCanvas = new Offcanvas(div)
|
||||
|
||||
jQueryMock.fn.offcanvas = Offcanvas.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.offcanvas.call(jQueryMock)
|
||||
|
||||
expect(Offcanvas.getInstance(div)).toEqual(offCanvas)
|
||||
})
|
||||
|
||||
it('should throw error on undefined method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const action = 'undefinedMethod'
|
||||
|
||||
jQueryMock.fn.offcanvas = Offcanvas.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.offcanvas.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
|
||||
it('should throw error on protected method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const action = '_getConfig'
|
||||
|
||||
jQueryMock.fn.offcanvas = Offcanvas.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.offcanvas.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
|
||||
it('should throw error if method "constructor" is being called', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const action = 'constructor'
|
||||
|
||||
jQueryMock.fn.offcanvas = Offcanvas.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.offcanvas.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
|
||||
it('should call offcanvas method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
const spy = spyOn(Offcanvas.prototype, 'show')
|
||||
|
||||
jQueryMock.fn.offcanvas = Offcanvas.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.offcanvas.call(jQueryMock, 'show')
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should create a offcanvas with given config', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
jQueryMock.fn.offcanvas = Offcanvas.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.offcanvas.call(jQueryMock, { scroll: true })
|
||||
|
||||
const offcanvas = Offcanvas.getInstance(div)
|
||||
expect(offcanvas).not.toBeNull()
|
||||
expect(offcanvas._config.scroll).toBeTrue()
|
||||
})
|
||||
})
|
||||
|
||||
describe('getInstance', () => {
|
||||
it('should return offcanvas instance', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import EventHandler from '../../src/dom/event-handler.js'
|
||||
import Popover from '../../src/popover.js'
|
||||
import {
|
||||
clearFixture, getFixture, jQueryMock, createEvent
|
||||
clearFixture, getFixture, createEvent
|
||||
} from '../helpers/fixture.js'
|
||||
|
||||
describe('Popover', () => {
|
||||
@@ -361,80 +361,6 @@ describe('Popover', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('jQueryInterface', () => {
|
||||
it('should create a popover', () => {
|
||||
fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
|
||||
|
||||
const popoverEl = fixtureEl.querySelector('a')
|
||||
|
||||
jQueryMock.fn.popover = Popover.jQueryInterface
|
||||
jQueryMock.elements = [popoverEl]
|
||||
|
||||
jQueryMock.fn.popover.call(jQueryMock)
|
||||
|
||||
expect(Popover.getInstance(popoverEl)).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should create a popover with a config object', () => {
|
||||
fixtureEl.innerHTML = '<a href="#" title="Popover">BS X</a>'
|
||||
|
||||
const popoverEl = fixtureEl.querySelector('a')
|
||||
|
||||
jQueryMock.fn.popover = Popover.jQueryInterface
|
||||
jQueryMock.elements = [popoverEl]
|
||||
|
||||
jQueryMock.fn.popover.call(jQueryMock, {
|
||||
content: 'Popover content'
|
||||
})
|
||||
|
||||
expect(Popover.getInstance(popoverEl)).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should not re create a popover', () => {
|
||||
fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
|
||||
|
||||
const popoverEl = fixtureEl.querySelector('a')
|
||||
const popover = new Popover(popoverEl)
|
||||
|
||||
jQueryMock.fn.popover = Popover.jQueryInterface
|
||||
jQueryMock.elements = [popoverEl]
|
||||
|
||||
jQueryMock.fn.popover.call(jQueryMock)
|
||||
|
||||
expect(Popover.getInstance(popoverEl)).toEqual(popover)
|
||||
})
|
||||
|
||||
it('should throw error on undefined method', () => {
|
||||
fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
|
||||
|
||||
const popoverEl = fixtureEl.querySelector('a')
|
||||
const action = 'undefinedMethod'
|
||||
|
||||
jQueryMock.fn.popover = Popover.jQueryInterface
|
||||
jQueryMock.elements = [popoverEl]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.popover.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
|
||||
it('should should call show method', () => {
|
||||
fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
|
||||
|
||||
const popoverEl = fixtureEl.querySelector('a')
|
||||
const popover = new Popover(popoverEl)
|
||||
|
||||
jQueryMock.fn.popover = Popover.jQueryInterface
|
||||
jQueryMock.elements = [popoverEl]
|
||||
|
||||
const spy = spyOn(popover, 'show')
|
||||
|
||||
jQueryMock.fn.popover.call(jQueryMock, 'show')
|
||||
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('getInstance', () => {
|
||||
it('should return popover instance', () => {
|
||||
fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap">BS X</a>'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import EventHandler from '../../src/dom/event-handler.js'
|
||||
import ScrollSpy from '../../src/scrollspy.js'
|
||||
import {
|
||||
clearFixture, createEvent, getFixture, jQueryMock
|
||||
clearFixture, createEvent, getFixture
|
||||
} from '../helpers/fixture.js'
|
||||
|
||||
describe('ScrollSpy', () => {
|
||||
@@ -648,111 +648,6 @@ describe('ScrollSpy', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('jQueryInterface', () => {
|
||||
it('should create a scrollspy', () => {
|
||||
fixtureEl.innerHTML = getDummyFixture()
|
||||
|
||||
const div = fixtureEl.querySelector('.content')
|
||||
|
||||
jQueryMock.fn.scrollspy = ScrollSpy.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.scrollspy.call(jQueryMock, { target: '#navBar' })
|
||||
|
||||
expect(ScrollSpy.getInstance(div)).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should create a scrollspy with given config', () => {
|
||||
fixtureEl.innerHTML = getDummyFixture()
|
||||
|
||||
const div = fixtureEl.querySelector('.content')
|
||||
|
||||
jQueryMock.fn.scrollspy = ScrollSpy.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.scrollspy.call(jQueryMock, { rootMargin: '100px' })
|
||||
const spy = spyOn(ScrollSpy.prototype, 'constructor')
|
||||
expect(spy).not.toHaveBeenCalledWith(div, { rootMargin: '100px' })
|
||||
|
||||
const scrollspy = ScrollSpy.getInstance(div)
|
||||
expect(scrollspy).not.toBeNull()
|
||||
expect(scrollspy._config.rootMargin).toEqual('100px')
|
||||
})
|
||||
|
||||
it('should not re create a scrollspy', () => {
|
||||
fixtureEl.innerHTML = getDummyFixture()
|
||||
|
||||
const div = fixtureEl.querySelector('.content')
|
||||
const scrollSpy = new ScrollSpy(div)
|
||||
|
||||
jQueryMock.fn.scrollspy = ScrollSpy.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.scrollspy.call(jQueryMock)
|
||||
|
||||
expect(ScrollSpy.getInstance(div)).toEqual(scrollSpy)
|
||||
})
|
||||
|
||||
it('should call a scrollspy method', () => {
|
||||
fixtureEl.innerHTML = getDummyFixture()
|
||||
|
||||
const div = fixtureEl.querySelector('.content')
|
||||
const scrollSpy = new ScrollSpy(div)
|
||||
|
||||
const spy = spyOn(scrollSpy, 'refresh')
|
||||
|
||||
jQueryMock.fn.scrollspy = ScrollSpy.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.scrollspy.call(jQueryMock, 'refresh')
|
||||
|
||||
expect(ScrollSpy.getInstance(div)).toEqual(scrollSpy)
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should throw error on undefined method', () => {
|
||||
fixtureEl.innerHTML = getDummyFixture()
|
||||
|
||||
const div = fixtureEl.querySelector('.content')
|
||||
const action = 'undefinedMethod'
|
||||
|
||||
jQueryMock.fn.scrollspy = ScrollSpy.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.scrollspy.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
|
||||
it('should throw error on protected method', () => {
|
||||
fixtureEl.innerHTML = getDummyFixture()
|
||||
|
||||
const div = fixtureEl.querySelector('.content')
|
||||
const action = '_getConfig'
|
||||
|
||||
jQueryMock.fn.scrollspy = ScrollSpy.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.scrollspy.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
|
||||
it('should throw error if method "constructor" is being called', () => {
|
||||
fixtureEl.innerHTML = getDummyFixture()
|
||||
|
||||
const div = fixtureEl.querySelector('.content')
|
||||
const action = 'constructor'
|
||||
|
||||
jQueryMock.fn.scrollspy = ScrollSpy.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.scrollspy.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getInstance', () => {
|
||||
it('should return scrollspy instance', () => {
|
||||
fixtureEl.innerHTML = getDummyFixture()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Tab from '../../src/tab.js'
|
||||
import {
|
||||
clearFixture, createEvent, getFixture, jQueryMock
|
||||
clearFixture, createEvent, getFixture
|
||||
} from '../helpers/fixture.js'
|
||||
|
||||
describe('Tab', () => {
|
||||
@@ -827,66 +827,6 @@ describe('Tab', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('jQueryInterface', () => {
|
||||
it('should create a tab', () => {
|
||||
fixtureEl.innerHTML = '<div class="nav"><div class="nav-link"></div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('.nav > div')
|
||||
|
||||
jQueryMock.fn.tab = Tab.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.tab.call(jQueryMock)
|
||||
|
||||
expect(Tab.getInstance(div)).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should not re create a tab', () => {
|
||||
fixtureEl.innerHTML = '<div class="nav"><div class="nav-link"></div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('.nav > div')
|
||||
const tab = new Tab(div)
|
||||
|
||||
jQueryMock.fn.tab = Tab.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.tab.call(jQueryMock)
|
||||
|
||||
expect(Tab.getInstance(div)).toEqual(tab)
|
||||
})
|
||||
|
||||
it('should call a tab method', () => {
|
||||
fixtureEl.innerHTML = '<div class="nav"><div class="nav-link"></div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('.nav > div')
|
||||
const tab = new Tab(div)
|
||||
|
||||
const spy = spyOn(tab, 'show')
|
||||
|
||||
jQueryMock.fn.tab = Tab.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.tab.call(jQueryMock, 'show')
|
||||
|
||||
expect(Tab.getInstance(div)).toEqual(tab)
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should throw error on undefined method', () => {
|
||||
fixtureEl.innerHTML = '<div class="nav"><div class="nav-link"></div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('.nav > div')
|
||||
const action = 'undefinedMethod'
|
||||
|
||||
jQueryMock.fn.tab = Tab.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.tab.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getInstance', () => {
|
||||
it('should return null if there is no instance', () => {
|
||||
expect(Tab.getInstance(fixtureEl)).toBeNull()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Toast from '../../src/toast.js'
|
||||
import {
|
||||
clearFixture, createEvent, getFixture, jQueryMock
|
||||
clearFixture, createEvent, getFixture
|
||||
} from '../helpers/fixture.js'
|
||||
|
||||
describe('Toast', () => {
|
||||
@@ -536,66 +536,6 @@ describe('Toast', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('jQueryInterface', () => {
|
||||
it('should create a toast', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
jQueryMock.fn.toast = Toast.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.toast.call(jQueryMock)
|
||||
|
||||
expect(Toast.getInstance(div)).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should not re create a toast', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const toast = new Toast(div)
|
||||
|
||||
jQueryMock.fn.toast = Toast.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.toast.call(jQueryMock)
|
||||
|
||||
expect(Toast.getInstance(div)).toEqual(toast)
|
||||
})
|
||||
|
||||
it('should call a toast method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const toast = new Toast(div)
|
||||
|
||||
const spy = spyOn(toast, 'show')
|
||||
|
||||
jQueryMock.fn.toast = Toast.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.toast.call(jQueryMock, 'show')
|
||||
|
||||
expect(Toast.getInstance(div)).toEqual(toast)
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should throw error on undefined method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const action = 'undefinedMethod'
|
||||
|
||||
jQueryMock.fn.toast = Toast.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.toast.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getInstance', () => {
|
||||
it('should return a toast instance', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
@@ -2,7 +2,7 @@ import EventHandler from '../../src/dom/event-handler.js'
|
||||
import Tooltip from '../../src/tooltip.js'
|
||||
import { noop } from '../../src/util/index.js'
|
||||
import {
|
||||
clearFixture, createEvent, getFixture, jQueryMock
|
||||
clearFixture, createEvent, getFixture
|
||||
} from '../helpers/fixture.js'
|
||||
|
||||
describe('Tooltip', () => {
|
||||
@@ -582,27 +582,6 @@ describe('Tooltip', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('should show a tooltip with a jquery element container', () => {
|
||||
return new Promise(resolve => {
|
||||
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
|
||||
|
||||
const tooltipEl = fixtureEl.querySelector('a')
|
||||
const tooltip = new Tooltip(tooltipEl, {
|
||||
container: {
|
||||
0: fixtureEl,
|
||||
jquery: 'jQuery'
|
||||
}
|
||||
})
|
||||
|
||||
tooltipEl.addEventListener('shown.bs.tooltip', () => {
|
||||
expect(fixtureEl.querySelector('.tooltip')).not.toBeNull()
|
||||
resolve()
|
||||
})
|
||||
|
||||
tooltip.show()
|
||||
})
|
||||
})
|
||||
|
||||
it('should show a tooltip with a selector in container', () => {
|
||||
return new Promise(resolve => {
|
||||
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
|
||||
@@ -1243,25 +1222,6 @@ describe('Tooltip', () => {
|
||||
expect().nothing()
|
||||
})
|
||||
|
||||
it('should add the content as a child of the element for jQuery elements', () => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<a href="#" rel="tooltip" title="Another tooltip">',
|
||||
' <div id="childContent"></div>',
|
||||
'</a>'
|
||||
].join('')
|
||||
|
||||
const tooltipEl = fixtureEl.querySelector('a')
|
||||
const childContent = fixtureEl.querySelector('div')
|
||||
const tooltip = new Tooltip(tooltipEl, {
|
||||
html: true
|
||||
})
|
||||
|
||||
tooltip.setContent({ '.tooltip': { 0: childContent, jquery: 'jQuery' } })
|
||||
tooltip.show()
|
||||
|
||||
expect(childContent.parentNode).toEqual(tooltip._getTipElement())
|
||||
})
|
||||
|
||||
it('should add the child text content in the element', () => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<a href="#" rel="tooltip" title="Another tooltip">',
|
||||
@@ -1522,64 +1482,4 @@ describe('Tooltip', () => {
|
||||
expect(tooltip2._getTitle()).toEqual('nothing')
|
||||
})
|
||||
})
|
||||
|
||||
describe('jQueryInterface', () => {
|
||||
it('should create a tooltip', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
jQueryMock.fn.tooltip = Tooltip.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.tooltip.call(jQueryMock)
|
||||
|
||||
expect(Tooltip.getInstance(div)).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should not re create a tooltip', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const tooltip = new Tooltip(div)
|
||||
|
||||
jQueryMock.fn.tooltip = Tooltip.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.tooltip.call(jQueryMock)
|
||||
|
||||
expect(Tooltip.getInstance(div)).toEqual(tooltip)
|
||||
})
|
||||
|
||||
it('should call a tooltip method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const tooltip = new Tooltip(div)
|
||||
|
||||
const spy = spyOn(tooltip, 'show')
|
||||
|
||||
jQueryMock.fn.tooltip = Tooltip.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.tooltip.call(jQueryMock, 'show')
|
||||
|
||||
expect(Tooltip.getInstance(div)).toEqual(tooltip)
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should throw error on undefined method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const action = 'undefinedMethod'
|
||||
|
||||
jQueryMock.fn.tooltip = Tooltip.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
expect(() => {
|
||||
jQueryMock.fn.tooltip.call(jQueryMock, action)
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -72,18 +72,6 @@ describe('Util', () => {
|
||||
expect(Util.isElement({})).toBeFalse()
|
||||
expect(Util.isElement(fixtureEl.querySelectorAll('.test'))).toBeFalse()
|
||||
})
|
||||
|
||||
it('should detect jQuery element', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const el = fixtureEl.querySelector('div')
|
||||
const fakejQuery = {
|
||||
0: el,
|
||||
jquery: 'foo'
|
||||
}
|
||||
|
||||
expect(Util.isElement(fakejQuery)).toBeTrue()
|
||||
})
|
||||
})
|
||||
|
||||
describe('getElement', () => {
|
||||
@@ -103,13 +91,6 @@ describe('Util', () => {
|
||||
expect(Util.getElement()).toBeNull()
|
||||
expect(Util.getElement(null)).toBeNull()
|
||||
expect(Util.getElement(fixtureEl.querySelectorAll('.test'))).toBeNull()
|
||||
|
||||
const fakejQueryObject = {
|
||||
0: el,
|
||||
jquery: 'foo'
|
||||
}
|
||||
|
||||
expect(Util.getElement(fakejQueryObject)).toEqual(el)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -425,39 +406,6 @@ describe('Util', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('getjQuery', () => {
|
||||
const fakejQuery = { trigger() {} }
|
||||
|
||||
beforeEach(() => {
|
||||
Object.defineProperty(window, 'jQuery', {
|
||||
value: fakejQuery,
|
||||
writable: true
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
window.jQuery = undefined
|
||||
})
|
||||
|
||||
it('should return jQuery object when present', () => {
|
||||
expect(Util.getjQuery()).toEqual(fakejQuery)
|
||||
})
|
||||
|
||||
it('should not return jQuery object when present if data-bs-no-jquery', () => {
|
||||
document.body.setAttribute('data-bs-no-jquery', '')
|
||||
|
||||
expect(window.jQuery).toEqual(fakejQuery)
|
||||
expect(Util.getjQuery()).toBeNull()
|
||||
|
||||
document.body.removeAttribute('data-bs-no-jquery')
|
||||
})
|
||||
|
||||
it('should not return jQuery if not present', () => {
|
||||
window.jQuery = undefined
|
||||
expect(Util.getjQuery()).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('onDOMContentLoaded', () => {
|
||||
it('should execute callbacks when DOMContentLoaded is fired and should not add more than one listener', () => {
|
||||
const spy = jasmine.createSpy()
|
||||
@@ -486,32 +434,6 @@ describe('Util', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('defineJQueryPlugin', () => {
|
||||
const fakejQuery = { fn: {} }
|
||||
|
||||
beforeEach(() => {
|
||||
Object.defineProperty(window, 'jQuery', {
|
||||
value: fakejQuery,
|
||||
writable: true
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
window.jQuery = undefined
|
||||
})
|
||||
|
||||
it('should define a plugin on the jQuery instance', () => {
|
||||
const pluginMock = Util.noop
|
||||
pluginMock.NAME = 'test'
|
||||
pluginMock.jQueryInterface = Util.noop
|
||||
|
||||
Util.defineJQueryPlugin(pluginMock)
|
||||
expect(fakejQuery.fn.test).toEqual(pluginMock.jQueryInterface)
|
||||
expect(fakejQuery.fn.test.Constructor).toEqual(pluginMock)
|
||||
expect(fakejQuery.fn.test.noConflict).toEqual(jasmine.any(Function))
|
||||
})
|
||||
})
|
||||
|
||||
describe('execute', () => {
|
||||
it('should execute if arg is function', () => {
|
||||
const spy = jasmine.createSpy('spy')
|
||||
|
||||
Generated
+2830
-1513
File diff suppressed because it is too large
Load Diff
+34
-34
@@ -42,7 +42,7 @@
|
||||
"start": "npm-run-all --parallel watch docs-serve",
|
||||
"bundlewatch": "bundlewatch --config .bundlewatch.config.json",
|
||||
"css": "npm-run-all css-compile css-prefix css-rtl css-minify",
|
||||
"css-compile": "sass --style expanded --source-map --embed-sources --no-error-css scss/:dist/css/",
|
||||
"css-compile": "sass --style expanded --source-map --embed-sources --no-error-css scss/bootstrap.scss:dist/css/bootstrap.css scss/bootstrap-grid.scss:dist/css/bootstrap-grid.css scss/bootstrap-reboot.scss:dist/css/bootstrap-reboot.css scss/bootstrap-utilities.scss:dist/css/bootstrap-utilities.css",
|
||||
"css-rtl": "cross-env NODE_ENV=RTL postcss --config build/postcss.config.mjs --dir \"dist/css\" --ext \".rtl.css\" \"dist/css/*.css\" \"!dist/css/*.min.css\" \"!dist/css/*.rtl.css\"",
|
||||
"css-lint": "npm-run-all --aggregate-output --continue-on-error --parallel css-lint-*",
|
||||
"css-lint-stylelint": "stylelint \"**/*.{css,scss}\" --cache --cache-location .cache/.stylelintcache",
|
||||
@@ -66,25 +66,25 @@
|
||||
"js-minify-standalone": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.js.map,includeSources,url=bootstrap.min.js.map\" --output dist/js/bootstrap.min.js dist/js/bootstrap.js",
|
||||
"js-minify-standalone-esm": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.esm.js.map,includeSources,url=bootstrap.esm.min.js.map\" --output dist/js/bootstrap.esm.min.js dist/js/bootstrap.esm.js",
|
||||
"js-minify-bundle": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.bundle.js.map,includeSources,url=bootstrap.bundle.min.js.map\" --output dist/js/bootstrap.bundle.min.js dist/js/bootstrap.bundle.js",
|
||||
"js-test": "npm-run-all --aggregate-output --parallel js-test-karma js-test-jquery js-test-integration-*",
|
||||
"js-test": "npm-run-all --aggregate-output --parallel js-test-karma js-test-integration-*",
|
||||
"js-debug": "cross-env DEBUG=true npm run js-test-karma",
|
||||
"js-test-karma": "karma start js/tests/karma.conf.js",
|
||||
"js-test-integration-bundle": "rollup --config js/tests/integration/rollup.bundle.js",
|
||||
"js-test-integration-modularity": "rollup --config js/tests/integration/rollup.bundle-modularity.js",
|
||||
"js-test-cloud": "cross-env BROWSERSTACK=true npm run js-test-karma",
|
||||
"js-test-jquery": "cross-env JQUERY=true npm run js-test-karma",
|
||||
"lint": "npm-run-all --aggregate-output --continue-on-error --parallel js-lint css-lint lockfile-lint",
|
||||
"lint": "npm-run-all --aggregate-output --continue-on-error --parallel js-lint css-lint lockfile-lint lint-mdx",
|
||||
"lint-mdx": "markdownlint \"site/src/content/**/*.mdx\"",
|
||||
"docs": "npm-run-all docs-build docs-lint",
|
||||
"docs-build": "npm run astro-build",
|
||||
"docs-compile": "npm run docs-build",
|
||||
"docs-vnu": "node build/vnu-jar.mjs",
|
||||
"docs-lint": "npm-run-all docs-prettier-check docs-vnu",
|
||||
"docs-html-validate": "node build/html-validate.mjs",
|
||||
"docs-lint": "npm-run-all docs-prettier-check docs-html-validate",
|
||||
"docs-prettier-check": "prettier --config site/.prettierrc.json -c --cache site",
|
||||
"docs-prettier-format": "prettier --config site/.prettierrc.json --write --cache site",
|
||||
"docs-serve": "npm run astro-dev",
|
||||
"docs-serve-only": "npx sirv-cli _site --port 9001",
|
||||
"lockfile-lint": "lockfile-lint --allowed-hosts npm --allowed-schemes https: --empty-hostname false --type npm --path package-lock.json",
|
||||
"update-deps": "ncu -u -x @docsearch/js,eslint,eslint-config-xo,eslint-plugin-unicorn,karma-browserstack-launcher,karma-rollup-preprocessor,sass,vnu-jar",
|
||||
"update-deps": "ncu -u -x @docsearch/js,eslint,eslint-config-xo,eslint-plugin-unicorn,karma-browserstack-launcher,karma-rollup-preprocessor,sass",
|
||||
"release": "npm-run-all dist release-sri docs-build release-zip*",
|
||||
"release-sri": "node build/generate-sri.mjs",
|
||||
"release-version": "node build/change-version.mjs",
|
||||
@@ -108,47 +108,47 @@
|
||||
"@popperjs/core": "^2.11.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/check": "^0.9.6",
|
||||
"@astrojs/markdown-remark": "^6.3.10",
|
||||
"@astrojs/mdx": "^4.3.13",
|
||||
"@astrojs/check": "^0.9.4",
|
||||
"@astrojs/markdown-remark": "^6.3.6",
|
||||
"@astrojs/mdx": "^4.3.5",
|
||||
"@astrojs/prism": "^3.3.0",
|
||||
"@astrojs/sitemap": "^3.6.0",
|
||||
"@babel/cli": "^7.28.3",
|
||||
"@babel/core": "^7.28.5",
|
||||
"@babel/preset-env": "^7.28.5",
|
||||
"@babel/core": "^7.28.4",
|
||||
"@babel/preset-env": "^7.28.3",
|
||||
"@docsearch/js": "^3.9.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@rollup/plugin-babel": "^6.1.0",
|
||||
"@rollup/plugin-commonjs": "^29.0.0",
|
||||
"@rollup/plugin-node-resolve": "^16.0.3",
|
||||
"@rollup/plugin-replace": "^6.0.3",
|
||||
"@rollup/plugin-babel": "^6.0.4",
|
||||
"@rollup/plugin-commonjs": "^28.0.6",
|
||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
||||
"@rollup/plugin-replace": "^6.0.2",
|
||||
"@stackblitz/sdk": "^1.11.0",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/mime": "^4.0.0",
|
||||
"@types/prismjs": "^1.26.5",
|
||||
"astro": "^5.16.6",
|
||||
"astro-auto-import": "^0.4.5",
|
||||
"autoprefixer": "^10.4.23",
|
||||
"astro": "^5.13.9",
|
||||
"astro-auto-import": "^0.4.4",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"bundlewatch": "^0.4.1",
|
||||
"clean-css-cli": "^5.6.3",
|
||||
"clipboard": "^2.0.11",
|
||||
"cross-env": "^10.1.0",
|
||||
"cross-env": "^10.0.0",
|
||||
"eslint": "8.57.1",
|
||||
"eslint-config-xo": "0.45.0",
|
||||
"eslint-plugin-html": "^8.1.3",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-markdown": "^5.1.0",
|
||||
"eslint-plugin-unicorn": "56.0.1",
|
||||
"find-unused-sass-variables": "^6.1.1",
|
||||
"find-unused-sass-variables": "^6.1.0",
|
||||
"github-slugger": "^2.0.0",
|
||||
"globby": "^16.0.0",
|
||||
"globby": "^14.1.0",
|
||||
"hammer-simulator": "0.0.1",
|
||||
"html-validate": "^8.24.1",
|
||||
"htmlparser2": "^10.0.0",
|
||||
"image-size": "^2.0.2",
|
||||
"ip": "^2.0.1",
|
||||
"jasmine": "^5.13.0",
|
||||
"jquery": "^3.7.1",
|
||||
"js-yaml": "^4.1.1",
|
||||
"jasmine": "^5.10.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"karma": "^6.4.4",
|
||||
"karma-browserstack-launcher": "1.4.0",
|
||||
"karma-chrome-launcher": "^3.2.0",
|
||||
@@ -159,28 +159,28 @@
|
||||
"karma-jasmine-html-reporter": "^2.1.0",
|
||||
"karma-rollup-preprocessor": "7.0.7",
|
||||
"lockfile-lint": "^4.14.1",
|
||||
"markdownlint-cli": "^0.45.0",
|
||||
"mime": "^4.1.0",
|
||||
"nodemon": "^3.1.11",
|
||||
"nodemon": "^3.1.10",
|
||||
"npm-run-all2": "^8.0.4",
|
||||
"postcss": "^8.5.6",
|
||||
"postcss-cli": "^11.0.1",
|
||||
"prettier": "^3.7.4",
|
||||
"prettier": "^3.6.2",
|
||||
"prettier-plugin-astro": "^0.14.1",
|
||||
"rehype-autolink-headings": "^7.1.0",
|
||||
"remark": "^15.0.1",
|
||||
"remark-html": "^16.0.1",
|
||||
"rollup": "^4.54.0",
|
||||
"rollup": "^4.52.0",
|
||||
"rollup-plugin-istanbul": "^5.0.0",
|
||||
"rtlcss": "^4.3.0",
|
||||
"sass": "1.78.0",
|
||||
"sass-true": "^10.1.0",
|
||||
"sass": "^1.90.0",
|
||||
"sass-true": "^9.0.0",
|
||||
"shelljs": "^0.10.0",
|
||||
"stylelint": "^16.26.1",
|
||||
"stylelint": "^16.24.0",
|
||||
"stylelint-config-twbs-bootstrap": "^16.1.0",
|
||||
"terser": "^5.44.1",
|
||||
"terser": "^5.44.0",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"vnu-jar": "25.11.25",
|
||||
"zod": "^4.2.1"
|
||||
"zod": "^4.1.9"
|
||||
},
|
||||
"files": [
|
||||
"dist/{css,js}/*.{css,js,map}",
|
||||
|
||||
+164
-130
@@ -1,153 +1,187 @@
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
@use "config" as *;
|
||||
@use "variables" as *;
|
||||
@use "functions" as *;
|
||||
@use "vendor/rfs" as *;
|
||||
@use "mixins/border-radius" as *;
|
||||
@use "mixins/transition" as *;
|
||||
@use "mixins/box-shadow" as *;
|
||||
@use "mixins/color-mode" as *;
|
||||
|
||||
.accordion {
|
||||
// scss-docs-start accordion-css-vars
|
||||
--#{$prefix}accordion-color: #{$accordion-color};
|
||||
--#{$prefix}accordion-bg: #{$accordion-bg};
|
||||
--#{$prefix}accordion-transition: #{$accordion-transition};
|
||||
--#{$prefix}accordion-border-color: #{$accordion-border-color};
|
||||
--#{$prefix}accordion-border-width: #{$accordion-border-width};
|
||||
--#{$prefix}accordion-border-radius: #{$accordion-border-radius};
|
||||
--#{$prefix}accordion-inner-border-radius: #{$accordion-inner-border-radius};
|
||||
--#{$prefix}accordion-btn-padding-x: #{$accordion-button-padding-x};
|
||||
--#{$prefix}accordion-btn-padding-y: #{$accordion-button-padding-y};
|
||||
--#{$prefix}accordion-btn-color: #{$accordion-button-color};
|
||||
--#{$prefix}accordion-btn-bg: #{$accordion-button-bg};
|
||||
--#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon)};
|
||||
--#{$prefix}accordion-btn-icon-width: #{$accordion-icon-width};
|
||||
--#{$prefix}accordion-btn-icon-transform: #{$accordion-icon-transform};
|
||||
--#{$prefix}accordion-btn-icon-transition: #{$accordion-icon-transition};
|
||||
--#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon)};
|
||||
--#{$prefix}accordion-btn-focus-box-shadow: #{$accordion-button-focus-box-shadow};
|
||||
--#{$prefix}accordion-body-padding-x: #{$accordion-body-padding-x};
|
||||
--#{$prefix}accordion-body-padding-y: #{$accordion-body-padding-y};
|
||||
--#{$prefix}accordion-active-color: #{$accordion-button-active-color};
|
||||
--#{$prefix}accordion-active-bg: #{$accordion-button-active-bg};
|
||||
// scss-docs-end accordion-css-vars
|
||||
}
|
||||
// scss-docs-start accordion-variables
|
||||
$accordion-padding-y: 1rem !default;
|
||||
$accordion-padding-x: 1.25rem !default;
|
||||
$accordion-color: var(--#{$prefix}body-color) !default;
|
||||
$accordion-bg: var(--#{$prefix}body-bg) !default;
|
||||
$accordion-border-width: var(--#{$prefix}border-width) !default;
|
||||
$accordion-border-color: var(--#{$prefix}border-color) !default;
|
||||
$accordion-border-radius: var(--#{$prefix}border-radius-lg) !default;
|
||||
$accordion-inner-border-radius: calc(#{$accordion-border-radius} - #{$accordion-border-width}) !default;
|
||||
|
||||
.accordion-button {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: var(--#{$prefix}accordion-btn-padding-y) var(--#{$prefix}accordion-btn-padding-x);
|
||||
@include font-size($font-size-base);
|
||||
color: var(--#{$prefix}accordion-btn-color);
|
||||
text-align: left; // Reset button style
|
||||
background-color: var(--#{$prefix}accordion-btn-bg);
|
||||
border: 0;
|
||||
@include border-radius(0);
|
||||
overflow-anchor: none;
|
||||
@include transition(var(--#{$prefix}accordion-transition));
|
||||
$accordion-body-padding-y: $accordion-padding-y !default;
|
||||
$accordion-body-padding-x: $accordion-padding-x !default;
|
||||
|
||||
&:not(.collapsed) {
|
||||
color: var(--#{$prefix}accordion-active-color);
|
||||
background-color: var(--#{$prefix}accordion-active-bg);
|
||||
box-shadow: inset 0 calc(-1 * var(--#{$prefix}accordion-border-width)) 0 var(--#{$prefix}accordion-border-color); // stylelint-disable-line function-disallowed-list
|
||||
$accordion-button-padding-y: $accordion-padding-y !default;
|
||||
$accordion-button-padding-x: $accordion-padding-x !default;
|
||||
$accordion-button-color: var(--#{$prefix}fg-2) !default;
|
||||
$accordion-button-bg: var(--#{$prefix}accordion-bg) !default;
|
||||
$accordion-transition: $btn-transition, border-radius .15s ease !default;
|
||||
$accordion-button-active-bg: var(--#{$prefix}bg-2) !default;
|
||||
$accordion-button-active-color: var(--#{$prefix}fg) !default;
|
||||
|
||||
&::after {
|
||||
background-image: var(--#{$prefix}accordion-btn-active-icon);
|
||||
transform: var(--#{$prefix}accordion-btn-icon-transform);
|
||||
}
|
||||
$accordion-button-focus-box-shadow: $btn-focus-box-shadow !default;
|
||||
|
||||
$accordion-icon-width: 1.25rem !default;
|
||||
$accordion-icon-transition: transform .2s ease-in-out !default;
|
||||
$accordion-icon-transform: rotate(-180deg) !default;
|
||||
$accordion-button-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='#000' stroke-linecap='round' stroke-linejoin='round'><path d='m2 5 6 6 6-6'/></svg>") !default;
|
||||
// scss-docs-end accordion-variables
|
||||
|
||||
@layer componenents {
|
||||
.accordion {
|
||||
// scss-docs-start accordion-css-vars
|
||||
--#{$prefix}accordion-color: #{$accordion-color};
|
||||
--#{$prefix}accordion-bg: #{$accordion-bg};
|
||||
--#{$prefix}accordion-transition: #{$accordion-transition};
|
||||
--#{$prefix}accordion-border-color: #{$accordion-border-color};
|
||||
--#{$prefix}accordion-border-width: #{$accordion-border-width};
|
||||
--#{$prefix}accordion-border-radius: #{$accordion-border-radius};
|
||||
--#{$prefix}accordion-inner-border-radius: #{$accordion-inner-border-radius};
|
||||
--#{$prefix}accordion-btn-padding-x: #{$accordion-button-padding-x};
|
||||
--#{$prefix}accordion-btn-padding-y: #{$accordion-button-padding-y};
|
||||
--#{$prefix}accordion-btn-color: #{$accordion-button-color};
|
||||
--#{$prefix}accordion-btn-bg: #{$accordion-button-bg};
|
||||
--#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon)};
|
||||
--#{$prefix}accordion-btn-icon-width: #{$accordion-icon-width};
|
||||
--#{$prefix}accordion-btn-icon-transform: #{$accordion-icon-transform};
|
||||
--#{$prefix}accordion-btn-icon-transition: #{$accordion-icon-transition};
|
||||
--#{$prefix}accordion-btn-focus-box-shadow: #{$accordion-button-focus-box-shadow};
|
||||
--#{$prefix}accordion-body-padding-x: #{$accordion-body-padding-x};
|
||||
--#{$prefix}accordion-body-padding-y: #{$accordion-body-padding-y};
|
||||
--#{$prefix}accordion-active-color: #{$accordion-button-active-color};
|
||||
--#{$prefix}accordion-active-bg: #{$accordion-button-active-bg};
|
||||
// scss-docs-end accordion-css-vars
|
||||
}
|
||||
|
||||
// Accordion icon
|
||||
&::after {
|
||||
flex-shrink: 0;
|
||||
width: var(--#{$prefix}accordion-btn-icon-width);
|
||||
height: var(--#{$prefix}accordion-btn-icon-width);
|
||||
margin-left: auto;
|
||||
content: "";
|
||||
background-image: var(--#{$prefix}accordion-btn-icon);
|
||||
background-repeat: no-repeat;
|
||||
background-size: var(--#{$prefix}accordion-btn-icon-width);
|
||||
@include transition(var(--#{$prefix}accordion-btn-icon-transition));
|
||||
}
|
||||
.accordion-button {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: var(--#{$prefix}accordion-btn-padding-y) var(--#{$prefix}accordion-btn-padding-x);
|
||||
@include font-size($font-size-base);
|
||||
color: var(--#{$prefix}accordion-btn-color);
|
||||
text-align: left; // Reset button style
|
||||
background-color: var(--#{$prefix}accordion-btn-bg);
|
||||
border: 0;
|
||||
@include border-radius(0);
|
||||
overflow-anchor: none;
|
||||
@include transition(var(--#{$prefix}accordion-transition));
|
||||
|
||||
&:hover {
|
||||
z-index: 2;
|
||||
}
|
||||
&:not(.collapsed) {
|
||||
color: var(--#{$prefix}accordion-active-color);
|
||||
background-color: var(--#{$prefix}accordion-active-bg);
|
||||
box-shadow: inset 0 calc(-1 * var(--#{$prefix}accordion-border-width)) 0 var(--#{$prefix}accordion-border-color);
|
||||
|
||||
&:focus {
|
||||
z-index: 3;
|
||||
outline: 0;
|
||||
box-shadow: var(--#{$prefix}accordion-btn-focus-box-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
.accordion-header {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.accordion-item {
|
||||
color: var(--#{$prefix}accordion-color);
|
||||
background-color: var(--#{$prefix}accordion-bg);
|
||||
border: var(--#{$prefix}accordion-border-width) solid var(--#{$prefix}accordion-border-color);
|
||||
|
||||
&:first-of-type {
|
||||
@include border-top-radius(var(--#{$prefix}accordion-border-radius));
|
||||
|
||||
> .accordion-header .accordion-button {
|
||||
@include border-top-radius(var(--#{$prefix}accordion-inner-border-radius));
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:first-of-type) {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
// Only set a border-radius on the last item if the accordion is collapsed
|
||||
&:last-of-type {
|
||||
@include border-bottom-radius(var(--#{$prefix}accordion-border-radius));
|
||||
|
||||
> .accordion-header .accordion-button {
|
||||
&.collapsed {
|
||||
@include border-bottom-radius(var(--#{$prefix}accordion-inner-border-radius));
|
||||
&::after {
|
||||
background-image: var(--#{$prefix}accordion-btn-active-icon);
|
||||
transform: var(--#{$prefix}accordion-btn-icon-transform);
|
||||
}
|
||||
}
|
||||
|
||||
> .accordion-collapse {
|
||||
// Accordion icon
|
||||
&::after {
|
||||
flex-shrink: 0;
|
||||
width: var(--#{$prefix}accordion-btn-icon-width);
|
||||
height: var(--#{$prefix}accordion-btn-icon-width);
|
||||
margin-left: auto;
|
||||
content: "";
|
||||
background-color: var(--#{$prefix}accordion-btn-color);
|
||||
mask: var(--#{$prefix}accordion-btn-icon) no-repeat center 100%;
|
||||
@include transition(var(--#{$prefix}accordion-btn-icon-transition));
|
||||
}
|
||||
|
||||
&:hover {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
z-index: 3;
|
||||
outline: 0;
|
||||
box-shadow: var(--#{$prefix}accordion-btn-focus-box-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
.accordion-header {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.accordion-item {
|
||||
color: var(--#{$prefix}accordion-color);
|
||||
background-color: var(--#{$prefix}accordion-bg);
|
||||
border: var(--#{$prefix}accordion-border-width) solid var(--#{$prefix}accordion-border-color);
|
||||
|
||||
&:first-of-type {
|
||||
@include border-top-radius(var(--#{$prefix}accordion-border-radius));
|
||||
|
||||
> .accordion-header .accordion-button {
|
||||
@include border-top-radius(var(--#{$prefix}accordion-inner-border-radius));
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:first-of-type) {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
// Only set a border-radius on the last item if the accordion is collapsed
|
||||
&:last-of-type {
|
||||
@include border-bottom-radius(var(--#{$prefix}accordion-border-radius));
|
||||
|
||||
> .accordion-header .accordion-button {
|
||||
&.collapsed {
|
||||
@include border-bottom-radius(var(--#{$prefix}accordion-inner-border-radius));
|
||||
}
|
||||
}
|
||||
|
||||
> .accordion-collapse {
|
||||
@include border-bottom-radius(var(--#{$prefix}accordion-border-radius));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.accordion-body {
|
||||
padding: var(--#{$prefix}accordion-body-padding-y) var(--#{$prefix}accordion-body-padding-x);
|
||||
}
|
||||
.accordion-body {
|
||||
padding: var(--#{$prefix}accordion-body-padding-y) var(--#{$prefix}accordion-body-padding-x);
|
||||
}
|
||||
|
||||
|
||||
// Flush accordion items
|
||||
//
|
||||
// Remove borders and border-radius to keep accordion items edge-to-edge.
|
||||
// Flush accordion items
|
||||
//
|
||||
// Remove borders and border-radius to keep accordion items edge-to-edge.
|
||||
|
||||
.accordion-flush {
|
||||
> .accordion-item {
|
||||
border-right: 0;
|
||||
border-left: 0;
|
||||
@include border-radius(0);
|
||||
|
||||
&:first-child { border-top: 0; }
|
||||
&:last-child { border-bottom: 0; }
|
||||
|
||||
// stylelint-disable selector-max-class
|
||||
> .accordion-collapse,
|
||||
> .accordion-header .accordion-button,
|
||||
> .accordion-header .accordion-button.collapsed {
|
||||
.accordion-flush {
|
||||
> .accordion-item {
|
||||
border-right: 0;
|
||||
border-left: 0;
|
||||
@include border-radius(0);
|
||||
}
|
||||
// stylelint-enable selector-max-class
|
||||
}
|
||||
}
|
||||
|
||||
@if $enable-dark-mode {
|
||||
@include color-mode(dark) {
|
||||
.accordion-button::after {
|
||||
--#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon-dark)};
|
||||
--#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon-dark)};
|
||||
&:first-child { border-top: 0; }
|
||||
&:last-child { border-bottom: 0; }
|
||||
|
||||
// stylelint-disable selector-max-class
|
||||
> .accordion-collapse,
|
||||
> .accordion-header .accordion-button,
|
||||
> .accordion-header .accordion-button.collapsed {
|
||||
@include border-radius(0);
|
||||
}
|
||||
// stylelint-enable selector-max-class
|
||||
}
|
||||
}
|
||||
|
||||
// @if $enable-dark-mode {
|
||||
// @include color-mode(dark) {
|
||||
// .accordion-button::after {
|
||||
// --#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon-dark)};
|
||||
// --#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon-dark)};
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user