migration net9.0
parent
6cf86bed47
commit
b4870a1814
@ -1,7 +0,0 @@
|
|||||||
on: workflow_call
|
|
||||||
jobs:
|
|
||||||
my_first_job:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Run my action
|
|
||||||
uses: ./.github/worklflows/dotnet
|
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Yavsc
|
||||||
|
After=syslog.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
Wants=postgresql.service
|
||||||
|
After=postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
RestartSec=5s
|
||||||
|
Type=simple
|
||||||
|
User=www-data
|
||||||
|
Group=www-data
|
||||||
|
WorkingDirectory=/srv/www/yavsc/
|
||||||
|
ExecStart=/srv/www/yavsc/Yavsc
|
||||||
|
Restart=always
|
||||||
|
Environment="HOME=/srv/www/yavsc"
|
||||||
|
Environment="ASPNETCORE_ENVIRONMENT=Production"
|
||||||
|
Environment="ASPNETCORE_ConnectionStrings__DefaultConnection=YOUR Postgresql CONNECTION STRING"
|
||||||
|
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||||
|
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||||
|
StandardOutput=syslog
|
||||||
|
StandardError=syslog
|
||||||
|
SyslogIdentifier=yavsc
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,169 @@
|
|||||||
|
\dt
|
||||||
|
select user,password from users;
|
||||||
|
select user,passwd from users;
|
||||||
|
select user from users;
|
||||||
|
select username,pwd from users;
|
||||||
|
select username,passwd from users;
|
||||||
|
select username,password from users;
|
||||||
|
\dT users
|
||||||
|
\d users
|
||||||
|
select username,passwd from users;
|
||||||
|
select username,passd from users;
|
||||||
|
\d users
|
||||||
|
select username,passw from users;
|
||||||
|
\d profiledata
|
||||||
|
select gregid from profiledata;
|
||||||
|
select uniqueid,gregid from profiledata;
|
||||||
|
select uniqueid,username from profile;
|
||||||
|
select uniqueid,username from profiles;
|
||||||
|
select uniqueid,gregid from profiledata;
|
||||||
|
select uniqueid,username from profiles;
|
||||||
|
select uniqueid,gregid from profiledata;
|
||||||
|
select uniqueid,gregid from profiledata;
|
||||||
|
select uniqueid,gregid from profiledata;
|
||||||
|
select uniqueid,gregid from profiledata;
|
||||||
|
select uniqueid,gregid from profiledata;
|
||||||
|
drop table GitRepositoryReference;
|
||||||
|
\use YavscDev
|
||||||
|
\use
|
||||||
|
\?
|
||||||
|
\use \?
|
||||||
|
\dt
|
||||||
|
drop table "GitRepositoryReference";
|
||||||
|
drop table "GitRepositoryReference" CASCADE;
|
||||||
|
exit;
|
||||||
|
\q
|
||||||
|
delete from "Project"
|
||||||
|
;
|
||||||
|
\q
|
||||||
|
create database dotnetmvc
|
||||||
|
;
|
||||||
|
create user dotnetmvc ;
|
||||||
|
grant CREATE on paul;
|
||||||
|
grant admins TO paul;
|
||||||
|
grant CREATE TO paul;
|
||||||
|
grant postgres TO paul;
|
||||||
|
grant paul TO postgres;
|
||||||
|
commit;
|
||||||
|
CREATE ROLE baget nocreatedb nocreaterole noreplication;
|
||||||
|
CREATE ROLE baget nocreatedb nocreaterole noreplication;
|
||||||
|
CREATE ROLE baget nocreatedb nocreaterole noreplication;
|
||||||
|
DROP ROLE baget;
|
||||||
|
commit;
|
||||||
|
alter role baget with superuser
|
||||||
|
;
|
||||||
|
commit;
|
||||||
|
\dT Project
|
||||||
|
\dt Project
|
||||||
|
\dt "Project"
|
||||||
|
desc "Project"
|
||||||
|
\?
|
||||||
|
\d "Project"
|
||||||
|
\d BlogSpot
|
||||||
|
\d Blogspot
|
||||||
|
\d "Blogspot"
|
||||||
|
\d "BlogSpot"
|
||||||
|
\d "BlogPost"
|
||||||
|
\d "BlogPost"
|
||||||
|
\d "BlogPost"
|
||||||
|
\d "BlogPost"
|
||||||
|
\d "BlogPost"
|
||||||
|
\d AspNetUsers
|
||||||
|
\d "AspNetUsers"
|
||||||
|
\dT "AspNetUsers"
|
||||||
|
update "AspNetUsers" set "LockoutEnable" = false;
|
||||||
|
\d "AspNetUsers"
|
||||||
|
\d "AspNetUsers"
|
||||||
|
update "AspNetUsers" set "LockoutEnabled" = false;
|
||||||
|
commit ;
|
||||||
|
\quit
|
||||||
|
update "AspNetUsers" set "LockoutEnabled" = true;
|
||||||
|
\s
|
||||||
|
\d
|
||||||
|
\dT
|
||||||
|
\?
|
||||||
|
\dn
|
||||||
|
\?
|
||||||
|
\?
|
||||||
|
\conninfo
|
||||||
|
\h create database
|
||||||
|
\h create user
|
||||||
|
create user forgejo with login 'ogVZ)f#m85zx';
|
||||||
|
create user forgejo with login;
|
||||||
|
\h alter user
|
||||||
|
alter user forgejo with PASSWORD 'ogVZ)f#m85zx';
|
||||||
|
commit:
|
||||||
|
commit;
|
||||||
|
commit;
|
||||||
|
\h create databse
|
||||||
|
\h create databse
|
||||||
|
create database forgejo with owner forgejo;
|
||||||
|
create user woodpecker with password 'aormb%$98zv<U&@' ;'
|
||||||
|
\sd
|
||||||
|
\?d
|
||||||
|
\dd
|
||||||
|
\dT
|
||||||
|
\dt
|
||||||
|
\d
|
||||||
|
\dd
|
||||||
|
\?
|
||||||
|
\dS
|
||||||
|
\?
|
||||||
|
\dD
|
||||||
|
\?
|
||||||
|
\dg
|
||||||
|
\?
|
||||||
|
\dn
|
||||||
|
\?
|
||||||
|
\l
|
||||||
|
\dl
|
||||||
|
\l
|
||||||
|
\dg
|
||||||
|
create database woodpecker with OWNER 'woodpecker';
|
||||||
|
select count(*) from "Users"
|
||||||
|
;
|
||||||
|
select count(*) from "AspNetUsers";
|
||||||
|
desc "AspNetUsers";
|
||||||
|
\dT "AspNetUsers"
|
||||||
|
\d "AspNetUsers"
|
||||||
|
update "AspNetUsers" set "EmailConfirmed" = true;
|
||||||
|
commit
|
||||||
|
;
|
||||||
|
select "UserName" from "AspNetUsers" ;
|
||||||
|
desc "AspNetUsers"
|
||||||
|
\d "AspNetUsers"
|
||||||
|
select "UserName", "Email" from "AspNetUsers" ;
|
||||||
|
select "UserName", "Email" from "AspNetUsers" ;
|
||||||
|
\d "AspNetUsers"
|
||||||
|
select "Id", "UserName", "Email" from "AspNetUsers" ;
|
||||||
|
\d "AspNetUsers"
|
||||||
|
select "Id", "UserName", "Email", "ConfirmedEmail" from "AspNetUsers" ;
|
||||||
|
\d "AspNetUsers"
|
||||||
|
select "Id", "UserName", "Email", "EmailConfirmed" from "AspNetUsers" ;
|
||||||
|
select * from "AspNetUsers" ;
|
||||||
|
\d "AspNetUsers"
|
||||||
|
select "Id", "UserName", "Email", "EmailConfirmed", "LockoutEnabe" from "AspNetUsers" ;
|
||||||
|
\d "AspNetUsers"
|
||||||
|
select "Id", "UserName", "Email", "EmailConfirmed", "LockoutEnabled" from "AspNetUsers" ;
|
||||||
|
upate AspNetUsers set LockoutEnabled = false;
|
||||||
|
update AspNetUsers set LockoutEnabled = false;
|
||||||
|
update "AspNetUsers" set "LockoutEnabled" = false;
|
||||||
|
commit;
|
||||||
|
select "Id", "UserName", "Email", "EmailConfirmed", "LockoutEnabled" from "AspNetUsers" ;
|
||||||
|
SELECT a."Id", a."AccessFailedCount", a."AllowMonthlyEmail", a."Avatar", a."BankInfoId", a."ConcurrencyStamp", a."DedicatedGoogleCalendar", a."DiskQuota", a."DiskUsage", a."Email", a."EmailConfirmed", a."FullName", a."LockoutEnabled", a."LockoutEnd", a."MaxFileSize", a."NormalizedEmail", a."NormalizedUserName", a."PasswordHash", a."PhoneNumber", a."PhoneNumberConfirmed", a."PostalAddressId", a."SecurityStamp", a."TwoFactorEnabled", a."UserName"
|
||||||
|
FROM "AspNetUsers" AS a
|
||||||
|
WHERE a."Email" = 'paul@pschneider.fr';
|
||||||
|
update "AspNetUsers" set "UserName" = 'Paul' where "Email" = 'paul@pschneider.fr';
|
||||||
|
update "AspNetUsers" set "UserName" = 'PaulS' where "Email" = 'contact@pschneider.fr';
|
||||||
|
update "AspNetUsers" set "UserName" = 'PaulSc' where "Email" = 'redienhcs.luap@gmail.com';
|
||||||
|
delete from Users where "userName" = 'pa'
|
||||||
|
;
|
||||||
|
delete from "Users" where "UserName" = 'pa';
|
||||||
|
delete from "AspNetUsers" where "UserName" = 'pa';
|
||||||
|
select "Id", "UserName", "Email", "EmailConfirmed", "LockoutEnabled" from "AspNetUsers" ;
|
||||||
|
\dT
|
||||||
|
\d
|
||||||
|
alter table "Activity" rename to "Activities";
|
||||||
|
\d
|
||||||
|
alter table "BlogPost" rename to "BlogSpot";
|
||||||
|
\s "BlogSpot"
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
[
|
||||||
|
'@babel/preset-env',
|
||||||
|
{
|
||||||
|
loose: true,
|
||||||
|
bugfixes: true,
|
||||||
|
modules: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
};
|
||||||
@ -1,44 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "bootstrap",
|
"name": "bootstrap",
|
||||||
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
|
"homepage": "https://github.com/twbs/bootstrap",
|
||||||
"keywords": [
|
"version": "5.3.6",
|
||||||
"css",
|
"_release": "5.3.6",
|
||||||
"js",
|
|
||||||
"less",
|
|
||||||
"mobile-first",
|
|
||||||
"responsive",
|
|
||||||
"front-end",
|
|
||||||
"framework",
|
|
||||||
"web"
|
|
||||||
],
|
|
||||||
"homepage": "http://getbootstrap.com",
|
|
||||||
"license": "MIT",
|
|
||||||
"moduleType": "globals",
|
|
||||||
"main": [
|
|
||||||
"less/bootstrap.less",
|
|
||||||
"dist/js/bootstrap.js"
|
|
||||||
],
|
|
||||||
"ignore": [
|
|
||||||
"/.*",
|
|
||||||
"_config.yml",
|
|
||||||
"CNAME",
|
|
||||||
"composer.json",
|
|
||||||
"CONTRIBUTING.md",
|
|
||||||
"docs",
|
|
||||||
"js/tests",
|
|
||||||
"test-infra"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"jquery": ">= 1.9.1"
|
|
||||||
},
|
|
||||||
"version": "3.3.5",
|
|
||||||
"_release": "3.3.5",
|
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "v3.3.5",
|
"tag": "v5.3.6",
|
||||||
"commit": "16b48259a62f576e52c903c476bd42b90ab22482"
|
"commit": "f849680d16a9695c9a6c9c062d6cff55ddcf071e"
|
||||||
},
|
},
|
||||||
"_source": "https://github.com/twbs/bootstrap.git",
|
"_source": "https://github.com/twbs/bootstrap.git",
|
||||||
"_target": "3.3.5",
|
"_target": "^5.3.6",
|
||||||
"_originalSource": "bootstrap"
|
"_originalSource": "bootstrap",
|
||||||
|
"_direct": true
|
||||||
}
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
# https://github.com/browserslist/browserslist#readme
|
||||||
|
|
||||||
|
>= 0.5%
|
||||||
|
last 2 major versions
|
||||||
|
not dead
|
||||||
|
Chrome >= 60
|
||||||
|
Firefox >= 60
|
||||||
|
Firefox ESR
|
||||||
|
iOS >= 12
|
||||||
|
Safari >= 12
|
||||||
|
not Explorer <= 11
|
||||||
|
not kaios <= 2.5 # fix floating label issues in Firefox (see https://github.com/postcss/autoprefixer/issues/1533)
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "./dist/css/bootstrap-grid.css",
|
||||||
|
"maxSize": "6.5 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/css/bootstrap-grid.min.css",
|
||||||
|
"maxSize": "6.0 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/css/bootstrap-reboot.css",
|
||||||
|
"maxSize": "3.5 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/css/bootstrap-reboot.min.css",
|
||||||
|
"maxSize": "3.25 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/css/bootstrap-utilities.css",
|
||||||
|
"maxSize": "11.75 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/css/bootstrap-utilities.min.css",
|
||||||
|
"maxSize": "10.75 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/css/bootstrap.css",
|
||||||
|
"maxSize": "32.5 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/css/bootstrap.min.css",
|
||||||
|
"maxSize": "30.25 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/js/bootstrap.bundle.js",
|
||||||
|
"maxSize": "43.0 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/js/bootstrap.bundle.min.js",
|
||||||
|
"maxSize": "23.5 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/js/bootstrap.esm.js",
|
||||||
|
"maxSize": "28.0 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/js/bootstrap.esm.min.js",
|
||||||
|
"maxSize": "18.25 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/js/bootstrap.js",
|
||||||
|
"maxSize": "28.75 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./dist/js/bootstrap.min.js",
|
||||||
|
"maxSize": "16.25 kB"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ci": {
|
||||||
|
"trackBranches": [
|
||||||
|
"main",
|
||||||
|
"v4-dev"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,131 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2",
|
||||||
|
"words": [
|
||||||
|
"affordance",
|
||||||
|
"allowfullscreen",
|
||||||
|
"Analyser",
|
||||||
|
"autohide",
|
||||||
|
"autohiding",
|
||||||
|
"autoplay",
|
||||||
|
"autoplays",
|
||||||
|
"autoplaying",
|
||||||
|
"blazingly",
|
||||||
|
"Blockquotes",
|
||||||
|
"Bootstrappers",
|
||||||
|
"borderless",
|
||||||
|
"Brotli",
|
||||||
|
"browserslist",
|
||||||
|
"browserslistrc",
|
||||||
|
"btncheck",
|
||||||
|
"btnradio",
|
||||||
|
"callout",
|
||||||
|
"callouts",
|
||||||
|
"camelCase",
|
||||||
|
"clearfix",
|
||||||
|
"Codesniffer",
|
||||||
|
"combinator",
|
||||||
|
"Contentful",
|
||||||
|
"Cpath",
|
||||||
|
"Crossfade",
|
||||||
|
"crossfading",
|
||||||
|
"cssgrid",
|
||||||
|
"Csvg",
|
||||||
|
"Datalists",
|
||||||
|
"Deque",
|
||||||
|
"discoverability",
|
||||||
|
"docsearch",
|
||||||
|
"docsref",
|
||||||
|
"dropend",
|
||||||
|
"dropleft",
|
||||||
|
"dropright",
|
||||||
|
"dropstart",
|
||||||
|
"dropup",
|
||||||
|
"dgst",
|
||||||
|
"errorf",
|
||||||
|
"favicon",
|
||||||
|
"favicons",
|
||||||
|
"fieldsets",
|
||||||
|
"flexbox",
|
||||||
|
"fullscreen",
|
||||||
|
"getbootstrap",
|
||||||
|
"Grayscale",
|
||||||
|
"Hoverable",
|
||||||
|
"hreflang",
|
||||||
|
"hstack",
|
||||||
|
"importmap",
|
||||||
|
"jsdelivr",
|
||||||
|
"Jumpstart",
|
||||||
|
"keyframes",
|
||||||
|
"libera",
|
||||||
|
"libman",
|
||||||
|
"Libsass",
|
||||||
|
"lightboxes",
|
||||||
|
"Lowercased",
|
||||||
|
"markdownify",
|
||||||
|
"mediaqueries",
|
||||||
|
"minifiers",
|
||||||
|
"misfunction",
|
||||||
|
"mkdir",
|
||||||
|
"monospace",
|
||||||
|
"mouseleave",
|
||||||
|
"navbars",
|
||||||
|
"navs",
|
||||||
|
"Neue",
|
||||||
|
"noindex",
|
||||||
|
"Noto",
|
||||||
|
"offcanvas",
|
||||||
|
"offcanvases",
|
||||||
|
"Packagist",
|
||||||
|
"popperjs",
|
||||||
|
"prebuild",
|
||||||
|
"prefersreducedmotion",
|
||||||
|
"prepended",
|
||||||
|
"printf",
|
||||||
|
"rects",
|
||||||
|
"relref",
|
||||||
|
"rgba",
|
||||||
|
"roboto",
|
||||||
|
"RTLCSS",
|
||||||
|
"ruleset",
|
||||||
|
"sassrc",
|
||||||
|
"screenreaders",
|
||||||
|
"scrollbars",
|
||||||
|
"scrollspy",
|
||||||
|
"Segoe",
|
||||||
|
"semibold",
|
||||||
|
"socio",
|
||||||
|
"srcset",
|
||||||
|
"stackblitz",
|
||||||
|
"stickied",
|
||||||
|
"Stylelint",
|
||||||
|
"subnav",
|
||||||
|
"tabbable",
|
||||||
|
"textareas",
|
||||||
|
"toggleable",
|
||||||
|
"topbar",
|
||||||
|
"touchend",
|
||||||
|
"twbs",
|
||||||
|
"unitless",
|
||||||
|
"unstylable",
|
||||||
|
"unstyled",
|
||||||
|
"Uppercased",
|
||||||
|
"urlize",
|
||||||
|
"urlquery",
|
||||||
|
"vbtn",
|
||||||
|
"viewports",
|
||||||
|
"Vite",
|
||||||
|
"vstack",
|
||||||
|
"walkthroughs",
|
||||||
|
"WCAG",
|
||||||
|
"zindex"
|
||||||
|
],
|
||||||
|
"language": "en-US",
|
||||||
|
"ignorePaths": [
|
||||||
|
".cspell.json",
|
||||||
|
"dist/",
|
||||||
|
"*.min.*",
|
||||||
|
"**/*rtl*",
|
||||||
|
"**/tests/**"
|
||||||
|
],
|
||||||
|
"useGitignore": true
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
# editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
**/*.min.js
|
||||||
|
**/dist/
|
||||||
|
**/vendor/
|
||||||
|
/_site/
|
||||||
|
/site/public/
|
||||||
|
/js/coverage/
|
||||||
|
/site/static/sw.js
|
||||||
|
/site/static/docs/**/assets/sw.js
|
||||||
|
/site/layouts/partials/
|
||||||
@ -0,0 +1,240 @@
|
|||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"extends": [
|
||||||
|
"plugin:import/errors",
|
||||||
|
"plugin:import/warnings",
|
||||||
|
"plugin:unicorn/recommended",
|
||||||
|
"xo",
|
||||||
|
"xo/browser"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"arrow-body-style": "off",
|
||||||
|
"capitalized-comments": "off",
|
||||||
|
"comma-dangle": [
|
||||||
|
"error",
|
||||||
|
"never"
|
||||||
|
],
|
||||||
|
"import/extensions": [
|
||||||
|
"error",
|
||||||
|
"ignorePackages",
|
||||||
|
{
|
||||||
|
"js": "always"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"import/first": "error",
|
||||||
|
"import/newline-after-import": "error",
|
||||||
|
"import/no-absolute-path": "error",
|
||||||
|
"import/no-amd": "error",
|
||||||
|
"import/no-cycle": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"ignoreExternal": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"import/no-duplicates": "error",
|
||||||
|
"import/no-extraneous-dependencies": "error",
|
||||||
|
"import/no-mutable-exports": "error",
|
||||||
|
"import/no-named-as-default": "error",
|
||||||
|
"import/no-named-as-default-member": "error",
|
||||||
|
"import/no-named-default": "error",
|
||||||
|
"import/no-self-import": "error",
|
||||||
|
"import/no-unassigned-import": [
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"import/no-useless-path-segments": "error",
|
||||||
|
"import/order": "error",
|
||||||
|
"indent": [
|
||||||
|
"error",
|
||||||
|
2,
|
||||||
|
{
|
||||||
|
"MemberExpression": "off",
|
||||||
|
"SwitchCase": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"logical-assignment-operators": "off",
|
||||||
|
"max-params": [
|
||||||
|
"warn",
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"multiline-ternary": [
|
||||||
|
"error",
|
||||||
|
"always-multiline"
|
||||||
|
],
|
||||||
|
"new-cap": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"properties": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-console": "error",
|
||||||
|
"no-negated-condition": "off",
|
||||||
|
"object-curly-spacing": [
|
||||||
|
"error",
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"operator-linebreak": [
|
||||||
|
"error",
|
||||||
|
"after"
|
||||||
|
],
|
||||||
|
"prefer-object-has-own": "off",
|
||||||
|
"prefer-template": "error",
|
||||||
|
"semi": [
|
||||||
|
"error",
|
||||||
|
"never"
|
||||||
|
],
|
||||||
|
"strict": "error",
|
||||||
|
"unicorn/explicit-length-check": "off",
|
||||||
|
"unicorn/filename-case": "off",
|
||||||
|
"unicorn/no-anonymous-default-export": "off",
|
||||||
|
"unicorn/no-array-callback-reference": "off",
|
||||||
|
"unicorn/no-array-method-this-argument": "off",
|
||||||
|
"unicorn/no-null": "off",
|
||||||
|
"unicorn/no-typeof-undefined": "off",
|
||||||
|
"unicorn/no-unused-properties": "error",
|
||||||
|
"unicorn/numeric-separators-style": "off",
|
||||||
|
"unicorn/prefer-array-flat": "off",
|
||||||
|
"unicorn/prefer-at": "off",
|
||||||
|
"unicorn/prefer-dom-node-dataset": "off",
|
||||||
|
"unicorn/prefer-module": "off",
|
||||||
|
"unicorn/prefer-query-selector": "off",
|
||||||
|
"unicorn/prefer-spread": "off",
|
||||||
|
"unicorn/prefer-string-raw": "off",
|
||||||
|
"unicorn/prefer-string-replace-all": "off",
|
||||||
|
"unicorn/prefer-structured-clone": "off",
|
||||||
|
"unicorn/prevent-abbreviations": "off"
|
||||||
|
},
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"build/**"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"browser": false,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"no-console": "off",
|
||||||
|
"unicorn/prefer-top-level-await": "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"js/**"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "module"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"js/tests/*.js",
|
||||||
|
"js/tests/integration/rollup*.js"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "script"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"js/tests/unit/**"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"jasmine": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"no-console": "off",
|
||||||
|
"unicorn/consistent-function-scoping": "off",
|
||||||
|
"unicorn/no-useless-undefined": "off",
|
||||||
|
"unicorn/prefer-add-event-listener": "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"js/tests/visual/**"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"html"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"html/html-extensions": [
|
||||||
|
".html"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"no-console": "off",
|
||||||
|
"no-new": "off",
|
||||||
|
"unicorn/no-array-for-each": "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"scss/tests/**"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "script"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"site/**"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"node": false
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "script",
|
||||||
|
"ecmaVersion": 2019
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"no-new": "off",
|
||||||
|
"unicorn/no-array-for-each": "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"site/src/assets/application.js",
|
||||||
|
"site/src/assets/partials/*.js",
|
||||||
|
"site/src/assets/search.js",
|
||||||
|
"site/src/assets/snippets.js",
|
||||||
|
"site/src/assets/stackblitz.js",
|
||||||
|
"site/src/plugins/*.js"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "module",
|
||||||
|
"ecmaVersion": 2020
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"**/*.md"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"markdown"
|
||||||
|
],
|
||||||
|
"processor": "markdown/markdown"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"**/*.md/*.js",
|
||||||
|
"**/*.md/*.mjs"
|
||||||
|
],
|
||||||
|
"extends": "plugin:markdown/recommended-legacy",
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"unicorn/prefer-node-protocol": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
# Enforce Unix newlines
|
||||||
|
* text=auto eol=lf
|
||||||
|
|
||||||
|
# Don't diff or textually merge source maps
|
||||||
|
*.map binary
|
||||||
|
|
||||||
|
bootstrap.css linguist-vendored=false
|
||||||
|
bootstrap.js linguist-vendored=false
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
*.js @twbs/js-review
|
||||||
|
*.css @twbs/css-review
|
||||||
|
*.scss @twbs/css-review
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
name: Report a bug
|
||||||
|
description: Tell us about a bug or issue you may have identified in Bootstrap.
|
||||||
|
title: "Provide a general summary of the issue"
|
||||||
|
labels: [bug]
|
||||||
|
assignees: "-"
|
||||||
|
body:
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Prerequisites
|
||||||
|
description: Take a couple minutes to help our maintainers work faster.
|
||||||
|
options:
|
||||||
|
- label: I have [searched](https://github.com/twbs/bootstrap/issues?utf8=%E2%9C%93&q=is%3Aissue) for duplicate or closed issues
|
||||||
|
required: true
|
||||||
|
- label: I have [validated](https://html5.validator.nu/) any HTML to avoid common problems
|
||||||
|
required: true
|
||||||
|
- label: I have read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/main/.github/CONTRIBUTING.md)
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened
|
||||||
|
attributes:
|
||||||
|
label: Describe the issue
|
||||||
|
description: Provide a summary of the issue and what you expected to happen, including specific steps to reproduce.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: reduced-test-case
|
||||||
|
attributes:
|
||||||
|
label: Reduced test cases
|
||||||
|
description: Include links [reduced test case](https://css-tricks.com/reduced-test-cases/) links or suggested fixes using CodePen ([v4 template](https://codepen.io/team/bootstrap/pen/yLabNQL) or [v5 template](https://codepen.io/team/bootstrap/pen/qBamdLj)).
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: os
|
||||||
|
attributes:
|
||||||
|
label: What operating system(s) are you seeing the problem on?
|
||||||
|
multiple: true
|
||||||
|
options:
|
||||||
|
- Windows
|
||||||
|
- macOS
|
||||||
|
- Android
|
||||||
|
- iOS
|
||||||
|
- Linux
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: browser
|
||||||
|
attributes:
|
||||||
|
label: What browser(s) are you seeing the problem on?
|
||||||
|
multiple: true
|
||||||
|
options:
|
||||||
|
- Chrome
|
||||||
|
- Safari
|
||||||
|
- Firefox
|
||||||
|
- Microsoft Edge
|
||||||
|
- Opera
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: What version of Bootstrap are you using?
|
||||||
|
placeholder: "e.g., v5.1.0 or v4.5.2"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
contact_links:
|
||||||
|
- name: Ask the community
|
||||||
|
url: https://github.com/twbs/bootstrap/discussions/new
|
||||||
|
about: Ask and discuss questions with other Bootstrap community members.
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
name: Feature request
|
||||||
|
description: Suggest new or updated features to include in Bootstrap.
|
||||||
|
title: "Suggest a new feature"
|
||||||
|
labels: [feature]
|
||||||
|
assignees: []
|
||||||
|
body:
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Prerequisites
|
||||||
|
description: Take a couple minutes to help our maintainers work faster.
|
||||||
|
options:
|
||||||
|
- label: I have [searched](https://github.com/twbs/bootstrap/issues?utf8=%E2%9C%93&q=is%3Aissue) for duplicate or closed feature requests
|
||||||
|
required: true
|
||||||
|
- label: I have read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/main/.github/CONTRIBUTING.md)
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: proposal
|
||||||
|
attributes:
|
||||||
|
label: Proposal
|
||||||
|
description: Provide detailed information for what we should add, including relevant links to prior art, screenshots, or live demos whenever possible.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: motivation
|
||||||
|
attributes:
|
||||||
|
label: Motivation and context
|
||||||
|
description: Tell us why this change is needed or helpful, and what problems it may help solve.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
### Bug reports
|
||||||
|
|
||||||
|
See the [contributing guidelines](CONTRIBUTING.md) for sharing bug reports.
|
||||||
|
|
||||||
|
### How-to
|
||||||
|
|
||||||
|
For general troubleshooting or help getting started:
|
||||||
|
|
||||||
|
- Ask and explore [our GitHub Discussions](https://github.com/twbs/bootstrap/discussions).
|
||||||
|
- Chat with fellow Bootstrappers in IRC. On the `irc.libera.chat` server, in the `#bootstrap` channel.
|
||||||
|
- Ask and explore Stack Overflow with the [`bootstrap-5`](https://stackoverflow.com/questions/tagged/bootstrap-5) tag.
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
name: "CodeQL config"
|
||||||
|
paths-ignore:
|
||||||
|
- dist
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
day: tuesday
|
||||||
|
time: "12:00"
|
||||||
|
timezone: Europe/Athens
|
||||||
|
- package-ecosystem: npm
|
||||||
|
directory: "/"
|
||||||
|
labels:
|
||||||
|
- dependencies
|
||||||
|
- v5
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
day: tuesday
|
||||||
|
time: "12:00"
|
||||||
|
timezone: Europe/Athens
|
||||||
|
versioning-strategy: increase
|
||||||
|
rebase-strategy: disabled
|
||||||
|
groups:
|
||||||
|
production-dependencies:
|
||||||
|
dependency-type: "production"
|
||||||
|
development-dependencies:
|
||||||
|
dependency-type: "development"
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
name-template: 'v$NEXT_MAJOR_VERSION'
|
||||||
|
tag-template: 'v$NEXT_MAJOR_VERSION'
|
||||||
|
prerelease: true
|
||||||
|
exclude-labels:
|
||||||
|
- 'skip-changelog'
|
||||||
|
categories:
|
||||||
|
- title: '❗ Breaking Changes'
|
||||||
|
labels:
|
||||||
|
- 'breaking-change'
|
||||||
|
- title: '🚀 Highlights'
|
||||||
|
labels:
|
||||||
|
- 'release-highlight'
|
||||||
|
- title: '🚀 Features'
|
||||||
|
labels:
|
||||||
|
- 'new-feature'
|
||||||
|
- 'feature'
|
||||||
|
- 'enhancement'
|
||||||
|
- title: '🐛 Bug fixes'
|
||||||
|
labels:
|
||||||
|
- 'fix'
|
||||||
|
- 'bugfix'
|
||||||
|
- 'bug'
|
||||||
|
- title: '⚡ Performance improvements'
|
||||||
|
labels:
|
||||||
|
- 'performance'
|
||||||
|
- title: '🎨 CSS'
|
||||||
|
labels:
|
||||||
|
- 'css'
|
||||||
|
- title: '☕️ JavaScript'
|
||||||
|
labels:
|
||||||
|
- 'js'
|
||||||
|
- title: '📖 Docs'
|
||||||
|
labels:
|
||||||
|
- 'docs'
|
||||||
|
- title: '🛠 Examples'
|
||||||
|
labels:
|
||||||
|
- 'examples'
|
||||||
|
- title: '🌎 Accessibility'
|
||||||
|
labels:
|
||||||
|
- 'accessibility'
|
||||||
|
- title: '🔧 Utility API'
|
||||||
|
labels:
|
||||||
|
- 'utility API'
|
||||||
|
- 'utilities'
|
||||||
|
- title: '🏭 Tests'
|
||||||
|
labels:
|
||||||
|
- 'tests'
|
||||||
|
- title: '🧰 Misc'
|
||||||
|
labels:
|
||||||
|
- 'build'
|
||||||
|
- 'meta'
|
||||||
|
- 'chore'
|
||||||
|
- 'CI'
|
||||||
|
- title: '📦 Dependencies'
|
||||||
|
labels:
|
||||||
|
- 'dependencies'
|
||||||
|
change-template: '- #$NUMBER: $TITLE'
|
||||||
|
template: |
|
||||||
|
## Changes
|
||||||
|
$CHANGES
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
name: BrowserStack
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "**"
|
||||||
|
- "!dependabot/**"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_COLOR: 2
|
||||||
|
NODE: 20
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
browserstack:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'twbs/bootstrap'
|
||||||
|
timeout-minutes: 30
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "${{ env.NODE }}"
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Install npm dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Run dist
|
||||||
|
run: npm run dist
|
||||||
|
|
||||||
|
- name: Run BrowserStack tests
|
||||||
|
run: npm run js-test-cloud
|
||||||
|
env:
|
||||||
|
BROWSER_STACK_ACCESS_KEY: "${{ secrets.BROWSER_STACK_ACCESS_KEY }}"
|
||||||
|
BROWSER_STACK_USERNAME: "${{ secrets.BROWSER_STACK_USERNAME }}"
|
||||||
|
GITHUB_SHA: "${{ github.sha }}"
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
name: Bundlewatch
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_COLOR: 2
|
||||||
|
NODE: 20
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
bundlewatch:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "${{ env.NODE }}"
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Install npm dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Run dist
|
||||||
|
run: npm run dist
|
||||||
|
|
||||||
|
- name: Run bundlewatch
|
||||||
|
run: npm run bundlewatch
|
||||||
|
env:
|
||||||
|
BUNDLEWATCH_GITHUB_TOKEN: "${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}"
|
||||||
|
CI_BRANCH_BASE: main
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
name: Compress Images
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '**.jpg'
|
||||||
|
- '**.jpeg'
|
||||||
|
- '**.png'
|
||||||
|
- '**.webp'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
# Only run on Pull Requests within the same repository, and not from forks.
|
||||||
|
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||||
|
name: calibreapp/image-actions
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
# allow calibreapp/image-actions to update PRs
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Compress Images
|
||||||
|
uses: calibreapp/image-actions@1.1.0
|
||||||
|
with:
|
||||||
|
githubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- v4-dev
|
||||||
|
- "!dependabot/**"
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- v4-dev
|
||||||
|
- "!dependabot/**"
|
||||||
|
schedule:
|
||||||
|
- cron: "0 2 * * 4"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v3
|
||||||
|
with:
|
||||||
|
config-file: ./.github/codeql/codeql-config.yml
|
||||||
|
languages: "javascript"
|
||||||
|
queries: +security-and-quality
|
||||||
|
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v3
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v3
|
||||||
|
with:
|
||||||
|
category: "/language:javascript"
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
name: cspell
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_COLOR: 2
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cspell:
|
||||||
|
permissions:
|
||||||
|
# allow streetsidesoftware/cspell-action to fetch files for commits and PRs
|
||||||
|
contents: read
|
||||||
|
pull-requests: read
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Run cspell
|
||||||
|
uses: streetsidesoftware/cspell-action@v6
|
||||||
|
with:
|
||||||
|
config: ".cspell.json"
|
||||||
|
files: "**/*.{md,mdx}"
|
||||||
|
inline: error
|
||||||
|
incremental_files_only: false
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
name: CSS
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_COLOR: 2
|
||||||
|
NODE: 20
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
css:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "${{ env.NODE }}"
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Install npm dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build CSS
|
||||||
|
run: npm run css
|
||||||
|
|
||||||
|
- name: Run CSS tests
|
||||||
|
run: npm run css-test
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
name: Docs
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_COLOR: 2
|
||||||
|
NODE: 20
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "${{ env.NODE }}"
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- run: java -version
|
||||||
|
|
||||||
|
- name: Install npm dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build docs
|
||||||
|
run: npm run docs-build
|
||||||
|
|
||||||
|
- name: Validate HTML
|
||||||
|
run: npm run docs-vnu
|
||||||
|
|
||||||
|
- name: Run linkinator
|
||||||
|
uses: JustinBeckwith/linkinator-action@v1
|
||||||
|
with:
|
||||||
|
paths: _site
|
||||||
|
recurse: true
|
||||||
|
verbosity: error
|
||||||
|
skip: "^(?!http://localhost)"
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
name: Close Issue Awaiting Reply
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
issue-close-require:
|
||||||
|
permissions:
|
||||||
|
# allow actions-cool/issues-helper to update issues and PRs
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'twbs/bootstrap'
|
||||||
|
steps:
|
||||||
|
- name: awaiting reply
|
||||||
|
uses: actions-cool/issues-helper@v3
|
||||||
|
with:
|
||||||
|
actions: "close-issues"
|
||||||
|
labels: "awaiting-reply"
|
||||||
|
inactive-day: 14
|
||||||
|
body: |
|
||||||
|
As the issue was labeled with `awaiting-reply`, but there has been no response in 14 days, this issue will be closed. If you have any questions, you can comment/reply.
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
name: Issue Labeled
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [labeled]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
issue-labeled:
|
||||||
|
permissions:
|
||||||
|
# allow actions-cool/issues-helper to update issues and PRs
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
if: github.repository == 'twbs/bootstrap'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: awaiting reply
|
||||||
|
if: github.event.label.name == 'needs-example'
|
||||||
|
uses: actions-cool/issues-helper@v3
|
||||||
|
with:
|
||||||
|
actions: "create-comment"
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
body: |
|
||||||
|
Hello @${{ github.event.issue.user.login }}. Bug reports must include a **live demo** of the issue. Per our [contributing guidelines](https://github.com/twbs/bootstrap/blob/main/.github/CONTRIBUTING.md), please create a reduced test case on [CodePen](https://codepen.io/) or [StackBlitz](https://stackblitz.com/) and report back with your link, Bootstrap version, and specific browser and Operating System details.
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
name: JS Tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_COLOR: 2
|
||||||
|
NODE: 20
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run:
|
||||||
|
permissions:
|
||||||
|
# allow coverallsapp/github-action to create new checks issues and fetch code
|
||||||
|
checks: write
|
||||||
|
contents: read
|
||||||
|
name: JS Tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.NODE }}
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Install npm dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Run dist
|
||||||
|
run: npm run js
|
||||||
|
|
||||||
|
- name: Run JS tests
|
||||||
|
run: npm run js-test
|
||||||
|
|
||||||
|
- name: Run Coveralls
|
||||||
|
uses: coverallsapp/github-action@v2
|
||||||
|
if: ${{ !github.event.repository.fork }}
|
||||||
|
with:
|
||||||
|
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
path-to-lcov: "./js/coverage/lcov.info"
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
name: Lint
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_COLOR: 2
|
||||||
|
NODE: 20
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "${{ env.NODE }}"
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Install npm dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Lint
|
||||||
|
run: npm run lint
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
name: CSS (node-sass)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_COLOR: 2
|
||||||
|
NODE: 20
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
css:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
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
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
name: Release notes
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update_release_draft:
|
||||||
|
permissions:
|
||||||
|
# allow release-drafter/release-drafter to create GitHub releases and add labels to PRs
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'twbs/bootstrap'
|
||||||
|
steps:
|
||||||
|
- uses: release-drafter/release-drafter@v6
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
# Prettier is only used for the website
|
||||||
|
|
||||||
|
site/.astro
|
||||||
|
site/dist
|
||||||
|
site/public
|
||||||
|
site/src/assets
|
||||||
|
site/src/scss
|
||||||
|
site/src/pages/**/*.md
|
||||||
|
site/src/pages/**/*.mdx
|
||||||
|
site/src/content/**/*.mdx
|
||||||
|
site/src/layouts/RedirectLayout.astro
|
||||||
|
site/static
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
**/*.min.css
|
||||||
|
**/dist/
|
||||||
|
**/vendor/
|
||||||
|
/_site/
|
||||||
|
/site/public/
|
||||||
|
/js/coverage/
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"stylelint-config-twbs-bootstrap"
|
||||||
|
],
|
||||||
|
"reportInvalidScopeDisables": true,
|
||||||
|
"reportNeedlessDisables": true,
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": "**/*.scss",
|
||||||
|
"rules": {
|
||||||
|
"declaration-property-value-disallowed-list": {
|
||||||
|
"border": "none",
|
||||||
|
"outline": "none"
|
||||||
|
},
|
||||||
|
"function-disallowed-list": [
|
||||||
|
"calc",
|
||||||
|
"lighten",
|
||||||
|
"darken"
|
||||||
|
],
|
||||||
|
"property-disallowed-list": [
|
||||||
|
"border-radius",
|
||||||
|
"border-top-left-radius",
|
||||||
|
"border-top-right-radius",
|
||||||
|
"border-bottom-right-radius",
|
||||||
|
"border-bottom-left-radius",
|
||||||
|
"transition"
|
||||||
|
],
|
||||||
|
"scss/dollar-variable-default": [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"ignore": "local"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scss/selector-no-union-class-name": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": "scss/**/*.{test,spec}.scss",
|
||||||
|
"rules": {
|
||||||
|
"scss/dollar-variable-default": null,
|
||||||
|
"declaration-no-important": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": "site/**/*.scss",
|
||||||
|
"rules": {
|
||||||
|
"scss/dollar-variable-default": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": "site/**/examples/**/*.css",
|
||||||
|
"rules": {
|
||||||
|
"comment-empty-line-before": null,
|
||||||
|
"property-no-vendor-prefix": null,
|
||||||
|
"selector-no-qualifying-type": null,
|
||||||
|
"value-no-vendor-prefix": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -1,531 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap's Gruntfile
|
|
||||||
* http://getbootstrap.com
|
|
||||||
* Copyright 2013-2015 Twitter, Inc.
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = function (grunt) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// Force use of Unix newlines
|
|
||||||
grunt.util.linefeed = '\n';
|
|
||||||
|
|
||||||
RegExp.quote = function (string) {
|
|
||||||
return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
||||||
};
|
|
||||||
|
|
||||||
var fs = require('fs');
|
|
||||||
var path = require('path');
|
|
||||||
var npmShrinkwrap = require('npm-shrinkwrap');
|
|
||||||
var generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js');
|
|
||||||
var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js');
|
|
||||||
var getLessVarsData = function () {
|
|
||||||
var filePath = path.join(__dirname, 'less/variables.less');
|
|
||||||
var fileContent = fs.readFileSync(filePath, { encoding: 'utf8' });
|
|
||||||
var parser = new BsLessdocParser(fileContent);
|
|
||||||
return { sections: parser.parseFile() };
|
|
||||||
};
|
|
||||||
var generateRawFiles = require('./grunt/bs-raw-files-generator.js');
|
|
||||||
var generateCommonJSModule = require('./grunt/bs-commonjs-generator.js');
|
|
||||||
var configBridge = grunt.file.readJSON('./grunt/configBridge.json', { encoding: 'utf8' });
|
|
||||||
|
|
||||||
Object.keys(configBridge.paths).forEach(function (key) {
|
|
||||||
configBridge.paths[key].forEach(function (val, i, arr) {
|
|
||||||
arr[i] = path.join('./docs/assets', val);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Project configuration.
|
|
||||||
grunt.initConfig({
|
|
||||||
|
|
||||||
// Metadata.
|
|
||||||
pkg: grunt.file.readJSON('package.json'),
|
|
||||||
banner: '/*!\n' +
|
|
||||||
' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
|
|
||||||
' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
|
|
||||||
' * Licensed under the <%= pkg.license %> license\n' +
|
|
||||||
' */\n',
|
|
||||||
jqueryCheck: configBridge.config.jqueryCheck.join('\n'),
|
|
||||||
jqueryVersionCheck: configBridge.config.jqueryVersionCheck.join('\n'),
|
|
||||||
|
|
||||||
// Task configuration.
|
|
||||||
clean: {
|
|
||||||
dist: 'dist',
|
|
||||||
docs: 'docs/dist'
|
|
||||||
},
|
|
||||||
|
|
||||||
jshint: {
|
|
||||||
options: {
|
|
||||||
jshintrc: 'js/.jshintrc'
|
|
||||||
},
|
|
||||||
grunt: {
|
|
||||||
options: {
|
|
||||||
jshintrc: 'grunt/.jshintrc'
|
|
||||||
},
|
|
||||||
src: ['Gruntfile.js', 'package.js', 'grunt/*.js']
|
|
||||||
},
|
|
||||||
core: {
|
|
||||||
src: 'js/*.js'
|
|
||||||
},
|
|
||||||
test: {
|
|
||||||
options: {
|
|
||||||
jshintrc: 'js/tests/unit/.jshintrc'
|
|
||||||
},
|
|
||||||
src: 'js/tests/unit/*.js'
|
|
||||||
},
|
|
||||||
assets: {
|
|
||||||
src: ['docs/assets/js/src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
jscs: {
|
|
||||||
options: {
|
|
||||||
config: 'js/.jscsrc'
|
|
||||||
},
|
|
||||||
grunt: {
|
|
||||||
src: '<%= jshint.grunt.src %>'
|
|
||||||
},
|
|
||||||
core: {
|
|
||||||
src: '<%= jshint.core.src %>'
|
|
||||||
},
|
|
||||||
test: {
|
|
||||||
src: '<%= jshint.test.src %>'
|
|
||||||
},
|
|
||||||
assets: {
|
|
||||||
options: {
|
|
||||||
requireCamelCaseOrUpperCaseIdentifiers: null
|
|
||||||
},
|
|
||||||
src: '<%= jshint.assets.src %>'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
concat: {
|
|
||||||
options: {
|
|
||||||
banner: '<%= banner %>\n<%= jqueryCheck %>\n<%= jqueryVersionCheck %>',
|
|
||||||
stripBanners: false
|
|
||||||
},
|
|
||||||
bootstrap: {
|
|
||||||
src: [
|
|
||||||
'js/transition.js',
|
|
||||||
'js/alert.js',
|
|
||||||
'js/button.js',
|
|
||||||
'js/carousel.js',
|
|
||||||
'js/collapse.js',
|
|
||||||
'js/dropdown.js',
|
|
||||||
'js/modal.js',
|
|
||||||
'js/tooltip.js',
|
|
||||||
'js/popover.js',
|
|
||||||
'js/scrollspy.js',
|
|
||||||
'js/tab.js',
|
|
||||||
'js/affix.js'
|
|
||||||
],
|
|
||||||
dest: 'dist/js/<%= pkg.name %>.js'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
uglify: {
|
|
||||||
options: {
|
|
||||||
compress: {
|
|
||||||
warnings: false
|
|
||||||
},
|
|
||||||
mangle: true,
|
|
||||||
preserveComments: 'some'
|
|
||||||
},
|
|
||||||
core: {
|
|
||||||
src: '<%= concat.bootstrap.dest %>',
|
|
||||||
dest: 'dist/js/<%= pkg.name %>.min.js'
|
|
||||||
},
|
|
||||||
customize: {
|
|
||||||
src: configBridge.paths.customizerJs,
|
|
||||||
dest: 'docs/assets/js/customize.min.js'
|
|
||||||
},
|
|
||||||
docsJs: {
|
|
||||||
src: configBridge.paths.docsJs,
|
|
||||||
dest: 'docs/assets/js/docs.min.js'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
qunit: {
|
|
||||||
options: {
|
|
||||||
inject: 'js/tests/unit/phantom.js'
|
|
||||||
},
|
|
||||||
files: 'js/tests/index.html'
|
|
||||||
},
|
|
||||||
|
|
||||||
less: {
|
|
||||||
compileCore: {
|
|
||||||
options: {
|
|
||||||
strictMath: true,
|
|
||||||
sourceMap: true,
|
|
||||||
outputSourceFiles: true,
|
|
||||||
sourceMapURL: '<%= pkg.name %>.css.map',
|
|
||||||
sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map'
|
|
||||||
},
|
|
||||||
src: 'less/bootstrap.less',
|
|
||||||
dest: 'dist/css/<%= pkg.name %>.css'
|
|
||||||
},
|
|
||||||
compileTheme: {
|
|
||||||
options: {
|
|
||||||
strictMath: true,
|
|
||||||
sourceMap: true,
|
|
||||||
outputSourceFiles: true,
|
|
||||||
sourceMapURL: '<%= pkg.name %>-theme.css.map',
|
|
||||||
sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map'
|
|
||||||
},
|
|
||||||
src: 'less/theme.less',
|
|
||||||
dest: 'dist/css/<%= pkg.name %>-theme.css'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
autoprefixer: {
|
|
||||||
options: {
|
|
||||||
browsers: configBridge.config.autoprefixerBrowsers
|
|
||||||
},
|
|
||||||
core: {
|
|
||||||
options: {
|
|
||||||
map: true
|
|
||||||
},
|
|
||||||
src: 'dist/css/<%= pkg.name %>.css'
|
|
||||||
},
|
|
||||||
theme: {
|
|
||||||
options: {
|
|
||||||
map: true
|
|
||||||
},
|
|
||||||
src: 'dist/css/<%= pkg.name %>-theme.css'
|
|
||||||
},
|
|
||||||
docs: {
|
|
||||||
src: ['docs/assets/css/src/docs.css']
|
|
||||||
},
|
|
||||||
examples: {
|
|
||||||
expand: true,
|
|
||||||
cwd: 'docs/examples/',
|
|
||||||
src: ['**/*.css'],
|
|
||||||
dest: 'docs/examples/'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
csslint: {
|
|
||||||
options: {
|
|
||||||
csslintrc: 'less/.csslintrc'
|
|
||||||
},
|
|
||||||
dist: [
|
|
||||||
'dist/css/bootstrap.css',
|
|
||||||
'dist/css/bootstrap-theme.css'
|
|
||||||
],
|
|
||||||
examples: [
|
|
||||||
'docs/examples/**/*.css'
|
|
||||||
],
|
|
||||||
docs: {
|
|
||||||
options: {
|
|
||||||
ids: false,
|
|
||||||
'overqualified-elements': false
|
|
||||||
},
|
|
||||||
src: 'docs/assets/css/src/docs.css'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
cssmin: {
|
|
||||||
options: {
|
|
||||||
// TODO: disable `zeroUnits` optimization once clean-css 3.2 is released
|
|
||||||
// and then simplify the fix for https://github.com/twbs/bootstrap/issues/14837 accordingly
|
|
||||||
compatibility: 'ie8',
|
|
||||||
keepSpecialComments: '*',
|
|
||||||
advanced: false
|
|
||||||
},
|
|
||||||
minifyCore: {
|
|
||||||
src: 'dist/css/<%= pkg.name %>.css',
|
|
||||||
dest: 'dist/css/<%= pkg.name %>.min.css'
|
|
||||||
},
|
|
||||||
minifyTheme: {
|
|
||||||
src: 'dist/css/<%= pkg.name %>-theme.css',
|
|
||||||
dest: 'dist/css/<%= pkg.name %>-theme.min.css'
|
|
||||||
},
|
|
||||||
docs: {
|
|
||||||
src: [
|
|
||||||
'docs/assets/css/src/pygments-manni.css',
|
|
||||||
'docs/assets/css/src/docs.css'
|
|
||||||
],
|
|
||||||
dest: 'docs/assets/css/docs.min.css'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
csscomb: {
|
|
||||||
options: {
|
|
||||||
config: 'less/.csscomb.json'
|
|
||||||
},
|
|
||||||
dist: {
|
|
||||||
expand: true,
|
|
||||||
cwd: 'dist/css/',
|
|
||||||
src: ['*.css', '!*.min.css'],
|
|
||||||
dest: 'dist/css/'
|
|
||||||
},
|
|
||||||
examples: {
|
|
||||||
expand: true,
|
|
||||||
cwd: 'docs/examples/',
|
|
||||||
src: '**/*.css',
|
|
||||||
dest: 'docs/examples/'
|
|
||||||
},
|
|
||||||
docs: {
|
|
||||||
src: 'docs/assets/css/src/docs.css',
|
|
||||||
dest: 'docs/assets/css/src/docs.css'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
copy: {
|
|
||||||
fonts: {
|
|
||||||
expand: true,
|
|
||||||
src: 'fonts/*',
|
|
||||||
dest: 'dist/'
|
|
||||||
},
|
|
||||||
docs: {
|
|
||||||
expand: true,
|
|
||||||
cwd: 'dist/',
|
|
||||||
src: [
|
|
||||||
'**/*'
|
|
||||||
],
|
|
||||||
dest: 'docs/dist/'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
connect: {
|
|
||||||
server: {
|
|
||||||
options: {
|
|
||||||
port: 3000,
|
|
||||||
base: '.'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
jekyll: {
|
|
||||||
options: {
|
|
||||||
config: '_config.yml'
|
|
||||||
},
|
|
||||||
docs: {},
|
|
||||||
github: {
|
|
||||||
options: {
|
|
||||||
raw: 'github: true'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
htmlmin: {
|
|
||||||
dist: {
|
|
||||||
options: {
|
|
||||||
collapseWhitespace: true,
|
|
||||||
conservativeCollapse: true,
|
|
||||||
minifyCSS: true,
|
|
||||||
minifyJS: true,
|
|
||||||
removeAttributeQuotes: true,
|
|
||||||
removeComments: true
|
|
||||||
},
|
|
||||||
expand: true,
|
|
||||||
cwd: '_gh_pages',
|
|
||||||
dest: '_gh_pages',
|
|
||||||
src: [
|
|
||||||
'**/*.html',
|
|
||||||
'!examples/**/*.html'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
jade: {
|
|
||||||
options: {
|
|
||||||
pretty: true,
|
|
||||||
data: getLessVarsData
|
|
||||||
},
|
|
||||||
customizerVars: {
|
|
||||||
src: 'docs/_jade/customizer-variables.jade',
|
|
||||||
dest: 'docs/_includes/customizer-variables.html'
|
|
||||||
},
|
|
||||||
customizerNav: {
|
|
||||||
src: 'docs/_jade/customizer-nav.jade',
|
|
||||||
dest: 'docs/_includes/nav/customize.html'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
htmllint: {
|
|
||||||
options: {
|
|
||||||
ignore: [
|
|
||||||
'Attribute "autocomplete" not allowed on element "button" at this point.',
|
|
||||||
'Attribute "autocomplete" not allowed on element "input" at this point.',
|
|
||||||
'Element "img" is missing required attribute "src".'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
src: '_gh_pages/**/*.html'
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
src: {
|
|
||||||
files: '<%= jshint.core.src %>',
|
|
||||||
tasks: ['jshint:core', 'qunit', 'concat']
|
|
||||||
},
|
|
||||||
test: {
|
|
||||||
files: '<%= jshint.test.src %>',
|
|
||||||
tasks: ['jshint:test', 'qunit']
|
|
||||||
},
|
|
||||||
less: {
|
|
||||||
files: 'less/**/*.less',
|
|
||||||
tasks: 'less'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
sed: {
|
|
||||||
versionNumber: {
|
|
||||||
pattern: (function () {
|
|
||||||
var old = grunt.option('oldver');
|
|
||||||
return old ? RegExp.quote(old) : old;
|
|
||||||
})(),
|
|
||||||
replacement: grunt.option('newver'),
|
|
||||||
exclude: [
|
|
||||||
'dist/fonts',
|
|
||||||
'docs/assets',
|
|
||||||
'fonts',
|
|
||||||
'js/tests/vendor',
|
|
||||||
'node_modules',
|
|
||||||
'test-infra'
|
|
||||||
],
|
|
||||||
recursive: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'saucelabs-qunit': {
|
|
||||||
all: {
|
|
||||||
options: {
|
|
||||||
build: process.env.TRAVIS_JOB_ID,
|
|
||||||
throttled: 10,
|
|
||||||
maxRetries: 3,
|
|
||||||
maxPollRetries: 4,
|
|
||||||
urls: ['http://127.0.0.1:3000/js/tests/index.html?hidepassed'],
|
|
||||||
browsers: grunt.file.readYAML('grunt/sauce_browsers.yml')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
exec: {
|
|
||||||
npmUpdate: {
|
|
||||||
command: 'npm update'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
compress: {
|
|
||||||
main: {
|
|
||||||
options: {
|
|
||||||
archive: 'bootstrap-<%= pkg.version %>-dist.zip',
|
|
||||||
mode: 'zip',
|
|
||||||
level: 9,
|
|
||||||
pretty: true
|
|
||||||
},
|
|
||||||
files: [
|
|
||||||
{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'dist/',
|
|
||||||
src: ['**'],
|
|
||||||
dest: 'bootstrap-<%= pkg.version %>-dist'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// These plugins provide necessary tasks.
|
|
||||||
require('load-grunt-tasks')(grunt, { scope: 'devDependencies' });
|
|
||||||
require('time-grunt')(grunt);
|
|
||||||
|
|
||||||
// Docs HTML validation task
|
|
||||||
grunt.registerTask('validate-html', ['jekyll:docs', 'htmllint']);
|
|
||||||
|
|
||||||
var runSubset = function (subset) {
|
|
||||||
return !process.env.TWBS_TEST || process.env.TWBS_TEST === subset;
|
|
||||||
};
|
|
||||||
var isUndefOrNonZero = function (val) {
|
|
||||||
return val === undefined || val !== '0';
|
|
||||||
};
|
|
||||||
|
|
||||||
// Test task.
|
|
||||||
var testSubtasks = [];
|
|
||||||
// Skip core tests if running a different subset of the test suite
|
|
||||||
if (runSubset('core') &&
|
|
||||||
// Skip core tests if this is a Savage build
|
|
||||||
process.env.TRAVIS_REPO_SLUG !== 'twbs-savage/bootstrap') {
|
|
||||||
testSubtasks = testSubtasks.concat(['dist-css', 'dist-js', 'csslint:dist', 'test-js', 'docs']);
|
|
||||||
}
|
|
||||||
// Skip HTML validation if running a different subset of the test suite
|
|
||||||
if (runSubset('validate-html') &&
|
|
||||||
// Skip HTML5 validator on Travis when [skip validator] is in the commit message
|
|
||||||
isUndefOrNonZero(process.env.TWBS_DO_VALIDATOR)) {
|
|
||||||
testSubtasks.push('validate-html');
|
|
||||||
}
|
|
||||||
// Only run Sauce Labs tests if there's a Sauce access key
|
|
||||||
if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' &&
|
|
||||||
// Skip Sauce if running a different subset of the test suite
|
|
||||||
runSubset('sauce-js-unit') &&
|
|
||||||
// Skip Sauce on Travis when [skip sauce] is in the commit message
|
|
||||||
isUndefOrNonZero(process.env.TWBS_DO_SAUCE)) {
|
|
||||||
testSubtasks.push('connect');
|
|
||||||
testSubtasks.push('saucelabs-qunit');
|
|
||||||
}
|
|
||||||
grunt.registerTask('test', testSubtasks);
|
|
||||||
grunt.registerTask('test-js', ['jshint:core', 'jshint:test', 'jshint:grunt', 'jscs:core', 'jscs:test', 'jscs:grunt', 'qunit']);
|
|
||||||
|
|
||||||
// JS distribution task.
|
|
||||||
grunt.registerTask('dist-js', ['concat', 'uglify:core', 'commonjs']);
|
|
||||||
|
|
||||||
// CSS distribution task.
|
|
||||||
grunt.registerTask('less-compile', ['less:compileCore', 'less:compileTheme']);
|
|
||||||
grunt.registerTask('dist-css', ['less-compile', 'autoprefixer:core', 'autoprefixer:theme', 'csscomb:dist', 'cssmin:minifyCore', 'cssmin:minifyTheme']);
|
|
||||||
|
|
||||||
// Full distribution task.
|
|
||||||
grunt.registerTask('dist', ['clean:dist', 'dist-css', 'copy:fonts', 'dist-js']);
|
|
||||||
|
|
||||||
// Default task.
|
|
||||||
grunt.registerTask('default', ['clean:dist', 'copy:fonts', 'test']);
|
|
||||||
|
|
||||||
// Version numbering task.
|
|
||||||
// grunt change-version-number --oldver=A.B.C --newver=X.Y.Z
|
|
||||||
// This can be overzealous, so its changes should always be manually reviewed!
|
|
||||||
grunt.registerTask('change-version-number', 'sed');
|
|
||||||
|
|
||||||
grunt.registerTask('build-glyphicons-data', function () { generateGlyphiconsData.call(this, grunt); });
|
|
||||||
|
|
||||||
// task for building customizer
|
|
||||||
grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']);
|
|
||||||
grunt.registerTask('build-customizer-html', 'jade');
|
|
||||||
grunt.registerTask('build-raw-files', 'Add scripts/less files to customizer.', function () {
|
|
||||||
var banner = grunt.template.process('<%= banner %>');
|
|
||||||
generateRawFiles(grunt, banner);
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.registerTask('commonjs', 'Generate CommonJS entrypoint module in dist dir.', function () {
|
|
||||||
var srcFiles = grunt.config.get('concat.bootstrap.src');
|
|
||||||
var destFilepath = 'dist/js/npm.js';
|
|
||||||
generateCommonJSModule(grunt, srcFiles, destFilepath);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Docs task.
|
|
||||||
grunt.registerTask('docs-css', ['autoprefixer:docs', 'autoprefixer:examples', 'csscomb:docs', 'csscomb:examples', 'cssmin:docs']);
|
|
||||||
grunt.registerTask('lint-docs-css', ['csslint:docs', 'csslint:examples']);
|
|
||||||
grunt.registerTask('docs-js', ['uglify:docsJs', 'uglify:customize']);
|
|
||||||
grunt.registerTask('lint-docs-js', ['jshint:assets', 'jscs:assets']);
|
|
||||||
grunt.registerTask('docs', ['docs-css', 'lint-docs-css', 'docs-js', 'lint-docs-js', 'clean:docs', 'copy:docs', 'build-glyphicons-data', 'build-customizer']);
|
|
||||||
|
|
||||||
grunt.registerTask('prep-release', ['dist', 'docs', 'jekyll:github', 'htmlmin', 'compress']);
|
|
||||||
|
|
||||||
// Task for updating the cached npm packages used by the Travis build (which are controlled by test-infra/npm-shrinkwrap.json).
|
|
||||||
// This task should be run and the updated file should be committed whenever Bootstrap's dependencies change.
|
|
||||||
grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', '_update-shrinkwrap']);
|
|
||||||
grunt.registerTask('_update-shrinkwrap', function () {
|
|
||||||
var done = this.async();
|
|
||||||
npmShrinkwrap({ dev: true, dirname: __dirname }, function (err) {
|
|
||||||
if (err) {
|
|
||||||
grunt.fail.warn(err);
|
|
||||||
}
|
|
||||||
var dest = 'test-infra/npm-shrinkwrap.json';
|
|
||||||
fs.renameSync('npm-shrinkwrap.json', dest);
|
|
||||||
grunt.log.writeln('File ' + dest.cyan + ' updated.');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
# Reporting Security Issues
|
||||||
|
|
||||||
|
The Bootstrap team and community take security issues in Bootstrap seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
|
||||||
|
|
||||||
|
To report a security issue, email [security@getbootstrap.com](mailto:security@getbootstrap.com) and include the word "SECURITY" in the subject line.
|
||||||
|
|
||||||
|
We'll endeavor to respond quickly, and will keep you updated throughout the process.
|
||||||
@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "bootstrap",
|
|
||||||
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
|
|
||||||
"keywords": [
|
|
||||||
"css",
|
|
||||||
"js",
|
|
||||||
"less",
|
|
||||||
"mobile-first",
|
|
||||||
"responsive",
|
|
||||||
"front-end",
|
|
||||||
"framework",
|
|
||||||
"web"
|
|
||||||
],
|
|
||||||
"homepage": "http://getbootstrap.com",
|
|
||||||
"license": "MIT",
|
|
||||||
"moduleType": "globals",
|
|
||||||
"main": [
|
|
||||||
"less/bootstrap.less",
|
|
||||||
"dist/js/bootstrap.js"
|
|
||||||
],
|
|
||||||
"ignore": [
|
|
||||||
"/.*",
|
|
||||||
"_config.yml",
|
|
||||||
"CNAME",
|
|
||||||
"composer.json",
|
|
||||||
"CONTRIBUTING.md",
|
|
||||||
"docs",
|
|
||||||
"js/tests",
|
|
||||||
"test-infra"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"jquery": ">= 1.9.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
import fs from 'node:fs/promises'
|
||||||
|
import path from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
||||||
|
const pkgJson = path.join(__dirname, '../package.json')
|
||||||
|
const pkg = JSON.parse(await fs.readFile(pkgJson, 'utf8'))
|
||||||
|
|
||||||
|
const year = new Date().getFullYear()
|
||||||
|
|
||||||
|
function getBanner(pluginFilename) {
|
||||||
|
return `/*!
|
||||||
|
* Bootstrap${pluginFilename ? ` ${pluginFilename}` : ''} v${pkg.version} (${pkg.homepage})
|
||||||
|
* Copyright 2011-${year} ${pkg.author}
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
|
*/`
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getBanner
|
||||||
@ -0,0 +1,108 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Script to build our plugins to use them separately.
|
||||||
|
* Copyright 2020-2025 The Bootstrap Authors
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import path from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { babel } from '@rollup/plugin-babel'
|
||||||
|
import { globby } from 'globby'
|
||||||
|
import { rollup } from 'rollup'
|
||||||
|
import banner from './banner.mjs'
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url)
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
||||||
|
const sourcePath = path.resolve(__dirname, '../js/src/').replace(/\\/g, '/')
|
||||||
|
const jsFiles = await globby(`${sourcePath}/**/*.js`)
|
||||||
|
|
||||||
|
// Array which holds the resolved plugins
|
||||||
|
const resolvedPlugins = []
|
||||||
|
|
||||||
|
// Trims the "js" extension and uppercases => first letter, hyphens, backslashes & slashes
|
||||||
|
const filenameToEntity = filename => filename.replace('.js', '')
|
||||||
|
.replace(/(?:^|-|\/|\\)[a-z]/g, str => str.slice(-1).toUpperCase())
|
||||||
|
|
||||||
|
for (const file of jsFiles) {
|
||||||
|
resolvedPlugins.push({
|
||||||
|
src: file,
|
||||||
|
dist: file.replace('src', 'dist'),
|
||||||
|
fileName: path.basename(file),
|
||||||
|
className: filenameToEntity(path.basename(file))
|
||||||
|
// safeClassName: filenameToEntity(path.relative(sourcePath, file))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const build = async plugin => {
|
||||||
|
/**
|
||||||
|
* @type {import('rollup').GlobalsOption}
|
||||||
|
*/
|
||||||
|
const globals = {}
|
||||||
|
|
||||||
|
const bundle = await rollup({
|
||||||
|
input: plugin.src,
|
||||||
|
plugins: [
|
||||||
|
babel({
|
||||||
|
// Only transpile our source code
|
||||||
|
exclude: 'node_modules/**',
|
||||||
|
// Include the helpers in each file, at most one copy of each
|
||||||
|
babelHelpers: 'bundled'
|
||||||
|
})
|
||||||
|
],
|
||||||
|
external(source) {
|
||||||
|
// Pattern to identify local files
|
||||||
|
const pattern = /^(\.{1,2})\//
|
||||||
|
|
||||||
|
// It's not a local file, e.g a Node.js package
|
||||||
|
if (!pattern.test(source)) {
|
||||||
|
globals[source] = source
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const usedPlugin = resolvedPlugins.find(plugin => {
|
||||||
|
return plugin.src.includes(source.replace(pattern, ''))
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!usedPlugin) {
|
||||||
|
throw new Error(`Source ${source} is not mapped!`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can change `Index` with `UtilIndex` etc if we use
|
||||||
|
// `safeClassName` instead of `className` everywhere
|
||||||
|
globals[path.normalize(usedPlugin.src)] = usedPlugin.className
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await bundle.write({
|
||||||
|
banner: banner(plugin.fileName),
|
||||||
|
format: 'umd',
|
||||||
|
name: plugin.className,
|
||||||
|
sourcemap: true,
|
||||||
|
globals,
|
||||||
|
generatedCode: 'es2015',
|
||||||
|
file: plugin.dist
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(`Built ${plugin.className}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const basename = path.basename(__filename)
|
||||||
|
const timeLabel = `[${basename}] finished`
|
||||||
|
|
||||||
|
console.log('Building individual plugins...')
|
||||||
|
console.time(timeLabel)
|
||||||
|
|
||||||
|
await Promise.all(Object.values(resolvedPlugins).map(plugin => build(plugin)))
|
||||||
|
|
||||||
|
console.timeEnd(timeLabel)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
})()
|
||||||
@ -0,0 +1,113 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Script to update version number references in the project.
|
||||||
|
* Copyright 2017-2025 The Bootstrap Authors
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { execFile } from 'node:child_process'
|
||||||
|
import fs from 'node:fs/promises'
|
||||||
|
import process from 'node:process'
|
||||||
|
|
||||||
|
const VERBOSE = process.argv.includes('--verbose')
|
||||||
|
const DRY_RUN = process.argv.includes('--dry') || process.argv.includes('--dry-run')
|
||||||
|
|
||||||
|
// These are the files we only care about replacing the version
|
||||||
|
const FILES = [
|
||||||
|
'README.md',
|
||||||
|
'config.yml',
|
||||||
|
'js/src/base-component.js',
|
||||||
|
'package.js',
|
||||||
|
'scss/mixins/_banner.scss',
|
||||||
|
'site/data/docs-versions.yml'
|
||||||
|
]
|
||||||
|
|
||||||
|
// Blame TC39... https://github.com/benjamingr/RegExp.escape/issues/37
|
||||||
|
function regExpQuote(string) {
|
||||||
|
return string.replace(/[$()*+-.?[\\\]^{|}]/g, '\\$&')
|
||||||
|
}
|
||||||
|
|
||||||
|
function regExpQuoteReplacement(string) {
|
||||||
|
return string.replace(/\$/g, '$$')
|
||||||
|
}
|
||||||
|
|
||||||
|
async function replaceRecursively(file, oldVersion, newVersion) {
|
||||||
|
const originalString = await fs.readFile(file, 'utf8')
|
||||||
|
const newString = originalString
|
||||||
|
.replace(
|
||||||
|
new RegExp(regExpQuote(oldVersion), 'g'),
|
||||||
|
regExpQuoteReplacement(newVersion)
|
||||||
|
)
|
||||||
|
// Also replace the version used by the rubygem,
|
||||||
|
// which is using periods (`.`) instead of hyphens (`-`)
|
||||||
|
.replace(
|
||||||
|
new RegExp(regExpQuote(oldVersion.replace(/-/g, '.')), 'g'),
|
||||||
|
regExpQuoteReplacement(newVersion.replace(/-/g, '.'))
|
||||||
|
)
|
||||||
|
|
||||||
|
// No need to move any further if the strings are identical
|
||||||
|
if (originalString === newString) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VERBOSE) {
|
||||||
|
console.log(`Found ${oldVersion} in ${file}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DRY_RUN) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await fs.writeFile(file, newString, 'utf8')
|
||||||
|
}
|
||||||
|
|
||||||
|
function bumpNpmVersion(newVersion) {
|
||||||
|
if (DRY_RUN) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
execFile('npm', ['version', newVersion, '--no-git-tag'], { shell: true }, error => {
|
||||||
|
if (error) {
|
||||||
|
console.error(error)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function showUsage(args) {
|
||||||
|
console.error('USAGE: change-version old_version new_version [--verbose] [--dry[-run]]')
|
||||||
|
console.error('Got arguments:', args)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main(args) {
|
||||||
|
let [oldVersion, newVersion] = args
|
||||||
|
|
||||||
|
if (!oldVersion || !newVersion) {
|
||||||
|
showUsage(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip any leading `v` from arguments because
|
||||||
|
// otherwise we will end up with duplicate `v`s
|
||||||
|
[oldVersion, newVersion] = [oldVersion, newVersion].map(arg => {
|
||||||
|
return arg.startsWith('v') ? arg.slice(1) : arg
|
||||||
|
})
|
||||||
|
|
||||||
|
if (oldVersion === newVersion) {
|
||||||
|
showUsage(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
bumpNpmVersion(newVersion)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Promise.all(
|
||||||
|
FILES.map(file => replaceRecursively(file, oldVersion, newVersion))
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main(process.argv.slice(2))
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Script to generate SRI hashes for use in our docs.
|
||||||
|
* Remember to use the same vendor files as the CDN ones,
|
||||||
|
* otherwise the hashes won't match!
|
||||||
|
*
|
||||||
|
* Copyright 2017-2025 The Bootstrap Authors
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import crypto from 'node:crypto'
|
||||||
|
import fs from 'node:fs'
|
||||||
|
import path from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import sh from 'shelljs'
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
||||||
|
sh.config.fatal = true
|
||||||
|
|
||||||
|
const configFile = path.join(__dirname, '../config.yml')
|
||||||
|
|
||||||
|
// Array of objects which holds the files to generate SRI hashes for.
|
||||||
|
// `file` is the path from the root folder
|
||||||
|
// `configPropertyName` is the config.yml variable's name of the file
|
||||||
|
const files = [
|
||||||
|
{
|
||||||
|
file: 'dist/css/bootstrap.min.css',
|
||||||
|
configPropertyName: 'css_hash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: 'dist/css/bootstrap.rtl.min.css',
|
||||||
|
configPropertyName: 'css_rtl_hash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: 'dist/js/bootstrap.min.js',
|
||||||
|
configPropertyName: 'js_hash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: 'dist/js/bootstrap.bundle.min.js',
|
||||||
|
configPropertyName: 'js_bundle_hash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: 'node_modules/@popperjs/core/dist/umd/popper.min.js',
|
||||||
|
configPropertyName: 'popper_hash'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const { file, configPropertyName } of files) {
|
||||||
|
fs.readFile(file, 'utf8', (error, data) => {
|
||||||
|
if (error) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
|
||||||
|
const algorithm = 'sha384'
|
||||||
|
const hash = crypto.createHash(algorithm).update(data, 'utf8').digest('base64')
|
||||||
|
const integrity = `${algorithm}-${hash}`
|
||||||
|
|
||||||
|
console.log(`${configPropertyName}: ${integrity}`)
|
||||||
|
|
||||||
|
sh.sed('-i', new RegExp(`^(\\s+${configPropertyName}:\\s+["'])\\S*(["'])`), `$1${integrity}$2`, configFile)
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
const mapConfig = {
|
||||||
|
inline: false,
|
||||||
|
annotation: true,
|
||||||
|
sourcesContent: true
|
||||||
|
}
|
||||||
|
|
||||||
|
export default context => {
|
||||||
|
return {
|
||||||
|
map: context.file.dirname.includes('examples') ? false : mapConfig,
|
||||||
|
plugins: {
|
||||||
|
autoprefixer: {
|
||||||
|
cascade: false
|
||||||
|
},
|
||||||
|
rtlcss: context.env === 'RTL'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
import path from 'node:path'
|
||||||
|
import process from 'node:process'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { babel } from '@rollup/plugin-babel'
|
||||||
|
import { nodeResolve } from '@rollup/plugin-node-resolve'
|
||||||
|
import replace from '@rollup/plugin-replace'
|
||||||
|
import banner from './banner.mjs'
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
||||||
|
const BUNDLE = process.env.BUNDLE === 'true'
|
||||||
|
const ESM = process.env.ESM === 'true'
|
||||||
|
|
||||||
|
let destinationFile = `bootstrap${ESM ? '.esm' : ''}`
|
||||||
|
const external = ['@popperjs/core']
|
||||||
|
const plugins = [
|
||||||
|
babel({
|
||||||
|
// Only transpile our source code
|
||||||
|
exclude: 'node_modules/**',
|
||||||
|
// Include the helpers in the bundle, at most one copy of each
|
||||||
|
babelHelpers: 'bundled'
|
||||||
|
})
|
||||||
|
]
|
||||||
|
const globals = {
|
||||||
|
'@popperjs/core': 'Popper'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BUNDLE) {
|
||||||
|
destinationFile += '.bundle'
|
||||||
|
// Remove last entry in external array to bundle Popper
|
||||||
|
external.pop()
|
||||||
|
delete globals['@popperjs/core']
|
||||||
|
plugins.push(
|
||||||
|
replace({
|
||||||
|
'process.env.NODE_ENV': '"production"',
|
||||||
|
preventAssignment: true
|
||||||
|
}),
|
||||||
|
nodeResolve()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const rollupConfig = {
|
||||||
|
input: path.resolve(__dirname, `../js/index.${ESM ? 'esm' : 'umd'}.js`),
|
||||||
|
output: {
|
||||||
|
banner: banner(),
|
||||||
|
file: path.resolve(__dirname, `../dist/js/${destinationFile}.js`),
|
||||||
|
format: ESM ? 'esm' : 'umd',
|
||||||
|
globals,
|
||||||
|
generatedCode: 'es2015'
|
||||||
|
},
|
||||||
|
external,
|
||||||
|
plugins
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ESM) {
|
||||||
|
rollupConfig.output.name = 'bootstrap'
|
||||||
|
}
|
||||||
|
|
||||||
|
export default rollupConfig
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
#!/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)
|
||||||
|
})
|
||||||
@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Script to create the built examples zip archive;
|
||||||
|
* requires the `zip` command to be present!
|
||||||
|
* Copyright 2020-2025 The Bootstrap Authors
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import fs from 'node:fs/promises'
|
||||||
|
import path from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import sh from 'shelljs'
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
||||||
|
const pkgJson = path.join(__dirname, '../package.json')
|
||||||
|
const pkg = JSON.parse(await fs.readFile(pkgJson, 'utf8'))
|
||||||
|
|
||||||
|
const versionShort = pkg.config.version_short
|
||||||
|
const distFolder = `bootstrap-${pkg.version}-examples`
|
||||||
|
const rootDocsDir = '_site'
|
||||||
|
const docsDir = `${rootDocsDir}/docs/${versionShort}/`
|
||||||
|
|
||||||
|
// these are the files we need in the examples
|
||||||
|
const cssFiles = [
|
||||||
|
'bootstrap.min.css',
|
||||||
|
'bootstrap.min.css.map',
|
||||||
|
'bootstrap.rtl.min.css',
|
||||||
|
'bootstrap.rtl.min.css.map'
|
||||||
|
]
|
||||||
|
const jsFiles = [
|
||||||
|
'bootstrap.bundle.min.js',
|
||||||
|
'bootstrap.bundle.min.js.map'
|
||||||
|
]
|
||||||
|
const imgFiles = [
|
||||||
|
'bootstrap-logo.svg',
|
||||||
|
'bootstrap-logo-white.svg'
|
||||||
|
]
|
||||||
|
const staticJsFiles = [
|
||||||
|
'color-modes.js'
|
||||||
|
]
|
||||||
|
|
||||||
|
sh.config.fatal = true
|
||||||
|
|
||||||
|
if (!sh.test('-d', rootDocsDir)) {
|
||||||
|
throw new Error(`The "${rootDocsDir}" folder does not exist, did you forget building the docs?`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// switch to the root dir
|
||||||
|
sh.cd(path.join(__dirname, '..'))
|
||||||
|
|
||||||
|
// remove any previously created folder/zip with the same name
|
||||||
|
sh.rm('-rf', [distFolder, `${distFolder}.zip`])
|
||||||
|
|
||||||
|
// create any folders so that `cp` works
|
||||||
|
sh.mkdir('-p', [
|
||||||
|
distFolder,
|
||||||
|
`${distFolder}/assets/brand/`,
|
||||||
|
`${distFolder}/assets/dist/css/`,
|
||||||
|
`${distFolder}/assets/dist/js/`,
|
||||||
|
`${distFolder}/assets/js/`
|
||||||
|
])
|
||||||
|
|
||||||
|
sh.cp('-Rf', `${docsDir}/examples/*`, distFolder)
|
||||||
|
|
||||||
|
for (const file of cssFiles) {
|
||||||
|
sh.cp('-f', `${docsDir}/dist/css/${file}`, `${distFolder}/assets/dist/css/`)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of jsFiles) {
|
||||||
|
sh.cp('-f', `${docsDir}/dist/js/${file}`, `${distFolder}/assets/dist/js/`)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of imgFiles) {
|
||||||
|
sh.cp('-f', `${docsDir}/assets/brand/${file}`, `${distFolder}/assets/brand/`)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of staticJsFiles) {
|
||||||
|
sh.cp('-f', `${docsDir}/assets/js/${file}`, `${distFolder}/assets/js/`)
|
||||||
|
}
|
||||||
|
|
||||||
|
sh.rm(`${distFolder}/index.html`)
|
||||||
|
|
||||||
|
// get all examples' HTML files
|
||||||
|
for (const file of sh.find(`${distFolder}/**/*.html`)) {
|
||||||
|
const fileContents = sh.cat(file)
|
||||||
|
.toString()
|
||||||
|
.replace(new RegExp(`"/docs/${versionShort}/`, 'g'), '"../')
|
||||||
|
.replace(/"..\/dist\//g, '"../assets/dist/')
|
||||||
|
.replace(/(<link href="\.\.\/.*) integrity=".*>/g, '$1>')
|
||||||
|
.replace(/(<script src="\.\.\/.*) integrity=".*>/g, '$1></script>')
|
||||||
|
.replace(/( +)<!-- favicons(.|\n)+<style>/i, ' <style>')
|
||||||
|
new sh.ShellString(fileContents).to(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the zip file
|
||||||
|
sh.exec(`zip -qr9 "${distFolder}.zip" "${distFolder}"`)
|
||||||
|
|
||||||
|
// remove the folder we created
|
||||||
|
sh.rm('-rf', distFolder)
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "twbs/bootstrap",
|
||||||
|
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
|
||||||
|
"keywords": [
|
||||||
|
"css",
|
||||||
|
"js",
|
||||||
|
"sass",
|
||||||
|
"mobile-first",
|
||||||
|
"responsive",
|
||||||
|
"front-end",
|
||||||
|
"framework",
|
||||||
|
"web"
|
||||||
|
],
|
||||||
|
"homepage": "https://getbootstrap.com/",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Mark Otto",
|
||||||
|
"email": "markdotto@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jacob Thornton",
|
||||||
|
"email": "jacobthornton@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/twbs/bootstrap/issues"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"replace": {
|
||||||
|
"twitter/bootstrap": "self.version"
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue