initial import

This commit is contained in:
2020-12-23 10:11:11 +01:00
commit be83b43a59
5600 changed files with 577973 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
var browsers = {
safariMac: {
base: 'BrowserStack',
os: 'OS X',
os_version: 'Yosemite',
browser: 'Safari',
browser_version: '8.0'
},
chromeMac: {
base: 'BrowserStack',
os: 'OS X',
os_version: 'Yosemite',
browser : 'Chrome',
browser_version : 'latest'
},
firefoxMac: {
base: 'BrowserStack',
os: 'OS X',
os_version: 'Yosemite',
browser: 'Firefox',
browser_version: 'latest'
},
'ie11Win8.1': {
base: 'BrowserStack',
os: 'Windows',
os_version: '8.1',
browser: 'IE',
browser_version: '11.0'
},
ie10Win8: {
base: 'BrowserStack',
os: 'Windows',
os_version: '8',
browser: 'IE',
browser_version: '10.0'
},
ie9Win7: {
base: 'BrowserStack',
os: 'Windows',
os_version: '7',
browser: 'IE',
browser_version: '9.0'
},
ie8Win7: {
base: 'BrowserStack',
os: 'Windows',
os_version: '7',
browser: 'IE',
browser_version: '8.0'
},
'chromeWin8.1': {
base: 'BrowserStack',
os: 'Windows',
os_version: '8.1',
browser: 'Chrome',
browser_version: 'latest'
},
'firefoxWin8.1': {
base: 'BrowserStack',
os: 'Windows',
os_version: '8.1',
browser: 'Firefox',
browser_version: 'latest'
},
iphone6: {
base: 'BrowserStack',
os: 'ios',
os_version: '11.2',
device: 'iPhone 6',
real_mobile: true
},
nexus5: {
base: 'BrowserStack',
os: 'android',
os_version: '4.4',
device: 'Google Nexus 5',
real_mobile: true
}
};
module.exports = {
list: browsers,
keys: Object.keys(browsers)
};

View File

@@ -0,0 +1,30 @@
/*!
* Bootstrap Grunt task for the CommonJS module generation
* https://getbootstrap.com/
* Copyright 2014-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
'use strict';
var fs = require('fs');
var path = require('path');
var COMMONJS_BANNER = '// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.\n';
module.exports = function generateCommonJSModule(grunt, srcFiles, destFilepath) {
var destDir = path.dirname(destFilepath);
function srcPathToDestRequire(srcFilepath) {
var requirePath = path.posix.relative(destDir, srcFilepath);
return 'require(\'' + requirePath + '\')';
}
var moduleOutputJs = COMMONJS_BANNER + srcFiles.map(srcPathToDestRequire).join('\n');
try {
fs.writeFileSync(destFilepath, moduleOutputJs);
} catch (err) {
grunt.fail.warn(err);
}
grunt.log.writeln('File ' + destFilepath.cyan + ' created.');
};

View File

@@ -0,0 +1,42 @@
/*!
* Bootstrap Grunt task for Glyphicons data generation
* https://getbootstrap.com/
* Copyright 2014-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
'use strict';
var fs = require('fs');
module.exports = function generateGlyphiconsData(grunt) {
// Pass encoding, utf8, so `readFileSync` will return a string instead of a
// buffer
var glyphiconsFile = fs.readFileSync('less/glyphicons.less', 'utf8');
var glyphiconsLines = glyphiconsFile.split('\n');
// Use any line that starts with ".glyphicon-" and capture the class name
var iconClassName = /^\.(glyphicon-[a-zA-Z0-9-]+)/;
var glyphiconsData = '# This file is generated via Grunt task. **Do not edit directly.**\n' +
'# See the \'build-glyphicons-data\' task in Gruntfile.js.\n\n';
var glyphiconsYml = 'docs/_data/glyphicons.yml';
for (var i = 0, len = glyphiconsLines.length; i < len; i++) {
var match = glyphiconsLines[i].match(iconClassName);
if (match !== null) {
glyphiconsData += '- ' + match[1] + '\n';
}
}
// Create the `_data` directory if it doesn't already exist
if (!fs.existsSync('docs/_data')) {
fs.mkdirSync('docs/_data');
}
try {
fs.writeFileSync(glyphiconsYml, glyphiconsData);
} catch (err) {
grunt.fail.warn(err);
}
grunt.log.writeln('File ' + glyphiconsYml.cyan + ' created.');
};

View File

@@ -0,0 +1,237 @@
/*!
* Bootstrap Grunt task for parsing Less docstrings
* https://getbootstrap.com/
* Copyright 2014-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
'use strict';
var Markdown = require('markdown-it');
function markdown2html(markdownString) {
var md = new Markdown();
// the slice removes the <p>...</p> wrapper output by Markdown processor
return md.render(markdownString.trim()).slice(3, -5);
}
/*
Mini-language:
//== This is a normal heading, which starts a section. Sections group variables together.
//## Optional description for the heading
//=== This is a subheading.
//** Optional description for the following variable. You **can** use Markdown in descriptions to discuss `<html>` stuff.
@foo: #fff;
//-- This is a heading for a section whose variables shouldn't be customizable
All other lines are ignored completely.
*/
var CUSTOMIZABLE_HEADING = /^[/]{2}={2}(.*)$/;
var UNCUSTOMIZABLE_HEADING = /^[/]{2}-{2}(.*)$/;
var SUBSECTION_HEADING = /^[/]{2}={3}(.*)$/;
var SECTION_DOCSTRING = /^[/]{2}#{2}(.+)$/;
var VAR_ASSIGNMENT = /^(@[a-zA-Z0-9_-]+):[ ]*([^ ;][^;]*);[ ]*$/;
var VAR_DOCSTRING = /^[/]{2}[*]{2}(.+)$/;
function Section(heading, customizable) {
this.heading = heading.trim();
this.id = this.heading.replace(/\s+/g, '-').toLowerCase();
this.customizable = customizable;
this.docstring = null;
this.subsections = [];
}
Section.prototype.addSubSection = function (subsection) {
this.subsections.push(subsection);
};
function SubSection(heading) {
this.heading = heading.trim();
this.id = this.heading.replace(/\s+/g, '-').toLowerCase();
this.variables = [];
}
SubSection.prototype.addVar = function (variable) {
this.variables.push(variable);
};
function VarDocstring(markdownString) {
this.html = markdown2html(markdownString);
}
function SectionDocstring(markdownString) {
this.html = markdown2html(markdownString);
}
function Variable(name, defaultValue) {
this.name = name;
this.defaultValue = defaultValue;
this.docstring = null;
}
function Tokenizer(fileContent) {
this._lines = fileContent.split('\n');
this._next = undefined;
}
Tokenizer.prototype.unshift = function (token) {
if (this._next !== undefined) {
throw new Error('Attempted to unshift twice!');
}
this._next = token;
};
Tokenizer.prototype._shift = function () {
// returning null signals EOF
// returning undefined means the line was ignored
if (this._next !== undefined) {
var result = this._next;
this._next = undefined;
return result;
}
if (this._lines.length <= 0) {
return null;
}
var line = this._lines.shift();
var match = null;
match = SUBSECTION_HEADING.exec(line);
if (match !== null) {
return new SubSection(match[1]);
}
match = CUSTOMIZABLE_HEADING.exec(line);
if (match !== null) {
return new Section(match[1], true);
}
match = UNCUSTOMIZABLE_HEADING.exec(line);
if (match !== null) {
return new Section(match[1], false);
}
match = SECTION_DOCSTRING.exec(line);
if (match !== null) {
return new SectionDocstring(match[1]);
}
match = VAR_DOCSTRING.exec(line);
if (match !== null) {
return new VarDocstring(match[1]);
}
var commentStart = line.lastIndexOf('//');
var varLine = commentStart === -1 ? line : line.slice(0, commentStart);
match = VAR_ASSIGNMENT.exec(varLine);
if (match !== null) {
return new Variable(match[1], match[2]);
}
return undefined;
};
Tokenizer.prototype.shift = function () {
while (true) {
var result = this._shift();
if (result === undefined) {
continue;
}
return result;
}
};
function Parser(fileContent) {
this._tokenizer = new Tokenizer(fileContent);
}
Parser.prototype.parseFile = function () {
var sections = [];
while (true) {
var section = this.parseSection();
if (section === null) {
if (this._tokenizer.shift() !== null) {
throw new Error('Unexpected unparsed section of file remains!');
}
return sections;
}
sections.push(section);
}
};
Parser.prototype.parseSection = function () {
var section = this._tokenizer.shift();
if (section === null) {
return null;
}
if (!(section instanceof Section)) {
throw new Error('Expected section heading; got: ' + JSON.stringify(section));
}
var docstring = this._tokenizer.shift();
if (docstring instanceof SectionDocstring) {
section.docstring = docstring;
} else {
this._tokenizer.unshift(docstring);
}
this.parseSubSections(section);
return section;
};
Parser.prototype.parseSubSections = function (section) {
while (true) {
var subsection = this.parseSubSection();
if (subsection === null) {
if (section.subsections.length === 0) {
// Presume an implicit initial subsection
subsection = new SubSection('');
this.parseVars(subsection);
} else {
break;
}
}
section.addSubSection(subsection);
}
if (section.subsections.length === 1 && !section.subsections[0].heading && section.subsections[0].variables.length === 0) {
// Ignore lone empty implicit subsection
section.subsections = [];
}
};
Parser.prototype.parseSubSection = function () {
var subsection = this._tokenizer.shift();
if (subsection instanceof SubSection) {
this.parseVars(subsection);
return subsection;
}
this._tokenizer.unshift(subsection);
return null;
};
Parser.prototype.parseVars = function (subsection) {
while (true) {
var variable = this.parseVar();
if (variable === null) {
return;
}
subsection.addVar(variable);
}
};
Parser.prototype.parseVar = function () {
var docstring = this._tokenizer.shift();
if (!(docstring instanceof VarDocstring)) {
this._tokenizer.unshift(docstring);
docstring = null;
}
var variable = this._tokenizer.shift();
if (variable instanceof Variable) {
variable.docstring = docstring;
return variable;
}
this._tokenizer.unshift(variable);
return null;
};
module.exports = Parser;

View File

@@ -0,0 +1,44 @@
/*!
* Bootstrap Grunt task for generating raw-files.min.js for the Customizer
* https://getbootstrap.com/
* Copyright 2014-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
'use strict';
var fs = require('fs');
var btoa = require('btoa');
var glob = require('glob');
function getFiles(type) {
var files = {};
var recursive = type === 'less';
var globExpr = recursive ? '/**/*' : '/*';
glob.sync(type + globExpr)
.filter(function (path) {
return type === 'fonts' ? true : new RegExp('\\.' + type + '$').test(path);
})
.forEach(function (fullPath) {
var relativePath = fullPath.replace(/^[^/]+\//, '');
files[relativePath] = type === 'fonts' ? btoa(fs.readFileSync(fullPath)) : fs.readFileSync(fullPath, 'utf8');
});
return 'var __' + type + ' = ' + JSON.stringify(files) + '\n';
}
module.exports = function generateRawFilesJs(grunt, banner) {
if (!banner) {
banner = '';
}
var dirs = ['js', 'less', 'fonts'];
var files = banner + dirs.map(getFiles).reduce(function (combined, file) {
return combined + file;
}, '');
var rawFilesJs = 'docs/assets/js/raw-files.min.js';
try {
fs.writeFileSync(rawFilesJs, files);
} catch (err) {
grunt.fail.warn(err);
}
grunt.log.writeln('File ' + rawFilesJs.cyan + ' created.');
};

View File

@@ -0,0 +1,109 @@
#!/usr/bin/env node
'use strict';
/* globals Set */
/*!
* Script to update version number references in the project.
* Copyright 2015-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
var fs = require('fs');
var path = require('path');
var sh = require('shelljs');
sh.config.fatal = true;
var sed = sh.sed;
// Blame TC39... https://github.com/benjamingr/RegExp.escape/issues/37
RegExp.quote = function (string) {
return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
};
RegExp.quoteReplacement = function (string) {
return string.replace(/[$]/g, '$$');
};
var DRY_RUN = false;
function walkAsync(directory, excludedDirectories, fileCallback, errback) {
if (excludedDirectories.has(path.parse(directory).base)) {
return;
}
fs.readdir(directory, function (err, names) {
if (err) {
errback(err);
return;
}
names.forEach(function (name) {
var filepath = path.join(directory, name);
fs.lstat(filepath, function (err, stats) {
if (err) {
process.nextTick(errback, err);
return;
}
if (stats.isSymbolicLink()) {
return;
}
else if (stats.isDirectory()) {
process.nextTick(walkAsync, filepath, excludedDirectories, fileCallback, errback);
}
else if (stats.isFile()) {
process.nextTick(fileCallback, filepath);
}
});
});
});
}
function replaceRecursively(directory, excludedDirectories, allowedExtensions, original, replacement) {
original = new RegExp(RegExp.quote(original), 'g');
replacement = RegExp.quoteReplacement(replacement);
var updateFile = !DRY_RUN ? function (filepath) {
if (allowedExtensions.has(path.parse(filepath).ext)) {
sed('-i', original, replacement, filepath);
}
} : function (filepath) {
if (allowedExtensions.has(path.parse(filepath).ext)) {
console.log('FILE: ' + filepath);
}
else {
console.log('EXCLUDED:' + filepath);
}
};
walkAsync(directory, excludedDirectories, updateFile, function (err) {
console.error('ERROR while traversing directory!:');
console.error(err);
process.exit(1);
});
}
function main(args) {
if (args.length !== 2) {
console.error('USAGE: change-version old_version new_version');
console.error('Got arguments:', args);
process.exit(1);
}
var oldVersion = args[0];
var newVersion = args[1];
var EXCLUDED_DIRS = new Set([
'.git',
'node_modules',
'vendor'
]);
var INCLUDED_EXTENSIONS = new Set([
// This extension whitelist is how we avoid modifying binary files
'',
'.css',
'.html',
'.js',
'.json',
'.less',
'.md',
'.nuspec',
'.ps1',
'.scss',
'.txt',
'.yml'
]);
replaceRecursively('.', EXCLUDED_DIRS, INCLUDED_EXTENSIONS, oldVersion, newVersion);
}
main(process.argv.slice(2));

View File

@@ -0,0 +1,54 @@
{
"paths": {
"customizerJs": [
"../assets/js/vendor/autoprefixer.js",
"../assets/js/vendor/less.min.js",
"../assets/js/vendor/jszip.min.js",
"../assets/js/vendor/uglify.min.js",
"../assets/js/vendor/Blob.js",
"../assets/js/vendor/FileSaver.js",
"../assets/js/raw-files.min.js",
"../assets/js/src/customizer.js"
],
"docsJs": [
"../assets/js/vendor/requestAnimationFrame-polyfill.js",
"../assets/js/vendor/base64.js",
"../assets/js/vendor/holder.min.js",
"../assets/js/vendor/clipboard.min.js",
"../assets/js/vendor/anchor.min.js",
"../assets/js/src/application.js",
"../assets/js/src/search.js",
"../assets/js/ie10-viewport-bug-workaround.js",
"../assets/js/ie-emulation-modes-warning.js"
]
},
"config": {
"autoprefixer": {
"browsers": [
"Android 2.3",
"Android >= 4",
"Chrome >= 20",
"Firefox >= 24",
"Explorer >= 8",
"iOS >= 6",
"Opera >= 12",
"Safari >= 6"
],
"cascade": false
},
"jqueryCheck": [
"if (typeof jQuery === 'undefined') {",
" throw new Error('Bootstrap\\'s JavaScript requires jQuery')",
"}\n"
],
"jqueryVersionCheck": [
"+function ($) {",
" 'use strict';",
" var version = $.fn.jquery.split(' ')[0].split('.')",
" if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {",
" throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')",
" }",
"}(jQuery);\n\n"
]
}
}

View File

@@ -0,0 +1,62 @@
#!/usr/bin/env node
'use strict';
/*!
* 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-2019 The Bootstrap Authors
* Copyright 2017-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
var crypto = require('crypto');
var fs = require('fs');
var path = require('path');
var replace = require('replace-in-file');
var 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
var files = [
{
file: 'dist/css/bootstrap.min.css',
configPropertyName: 'css_hash'
},
{
file: 'dist/css/bootstrap-theme.min.css',
configPropertyName: 'css_theme_hash'
},
{
file: 'dist/js/bootstrap.min.js',
configPropertyName: 'js_hash'
}
];
files.forEach(function (file) {
fs.readFile(file.file, 'utf8', function (err, data) {
if (err) {
throw err;
}
var algo = 'sha384';
var hash = crypto.createHash(algo).update(data, 'utf8').digest('base64');
var integrity = algo + '-' + hash;
console.log(file.configPropertyName + ': ' + integrity);
try {
replace.sync({
files: configFile,
from: new RegExp('(\\s' + file.configPropertyName + ':\\s+"|\')(\\S+)("|\')'),
to: '$1' + integrity + '$3'
});
} catch (error) {
console.error('Error occurred:', error);
}
});
});

View File

@@ -0,0 +1,79 @@
'use strict';
var ip = require('ip');
var browserConfig = require('./browsers');
var browserStack = process.env.BROWSER === 'true';
module.exports = function (config) {
var conf = {
basePath: '../',
frameworks: ['qunit'],
plugins: ['karma-qunit'],
// list of files / patterns to load in the browser
files: [
'js/tests/vendor/jquery.min.js',
'js/tooltip.js',
'js/!(tooltip).js',
'js/tests/unit/*.js'
],
reporters: ['dots'],
port: 9876,
colors: true,
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_ERROR || config.LOG_WARN,
autoWatch: false,
singleRun: true,
concurrency: Infinity,
client: {
qunit: {
showUI: true
}
}
};
if (browserStack) {
conf.hostname = ip.address();
conf.browserStack = {
username: process.env.BROWSER_STACK_USERNAME,
accessKey: process.env.BROWSER_STACK_ACCESS_KEY,
build: 'bootstrap-v3-' + new Date().toISOString(),
project: 'Bootstrap v3',
retryLimit: 1
};
conf.plugins.push('karma-browserstack-launcher');
conf.customLaunchers = browserConfig.list;
conf.browsers = browserConfig.keys;
conf.reporters.push('BrowserStack');
} else {
conf.frameworks.push('detectBrowsers');
conf.plugins.push(
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-detect-browsers'
);
conf.detectBrowsers = {
usePhantomJS: false,
postDetection: function (availableBrowser) {
if (typeof process.env.TRAVIS_JOB_ID !== 'undefined' || availableBrowser.includes('Chrome')) {
return ['ChromeHeadless'];
}
if (availableBrowser.includes('Firefox')) {
return ['FirefoxHeadless'];
}
throw new Error('Please install Firefox or Chrome');
}
};
conf.customLaunchers = {
FirefoxHeadless: {
base: 'Firefox',
flags: ['-headless']
}
};
}
config.set(conf);
};