Skip to content
Snippets Groups Projects
Commit d98c2135 authored by Ivica Puljic's avatar Ivica Puljic Committed by Ivica Puljic
Browse files

Issue #3324508 by pivica, Berdir: Update node libs to latest versions

parent 9ebcfb3a
No related branches found
No related tags found
No related merge requests found
Showing
with 993 additions and 1388 deletions
.npmrc 0 → 100644
engine-strict=true
.nvmrc 0 → 100644
18
......@@ -45,7 +45,7 @@ Goals & Features
- Presents and use good development workflow for building themes.
- Light weight.
- BEM oriented.
- Implements bs_bootstrap Bootstrap 4 based child theme.
- Implements bs_bootstrap which is Bootstrap 4 based child theme.
- Gulp build process.
- Semantically clean HTML as much as possible - use mixins and don't hardcode
CSS framework classes where it does not make sense.
......@@ -60,45 +60,55 @@ Goals & Features
Documentation
-------------
For up to date documentation please visit https://www.drupal.org/docs/8/themes/bs-base.
For up-to-date documentation please visit https://www.drupal.org/docs/8/themes/bs-base.
### Install
We need some global dependencies: node, npm, and gulp-cli.
For debian based system check https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions.
To install Node.js 8.x version and the rest of global dependencies
commands are basically:
For node and npm it is recommended to use nvm to install and manage different
node versions on your system. For installation of nvm check https://github.com/nvm-sh/nvm#installing-and-updating.
Current version of bs_base requires node 18.
To install gulp-cli execute:
```
$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
$ sudo apt-get install -y nodejs
$ npm install -g gulp-cli
```
Instead of npm you can use pnpm installer which is much faster and requires
less resources on your system. Check https://pnpm.io/installation for more
details how to install pnpm on your system.
After all dependencies are installed run:
```
$ drush bs-tc bs_bootstrap custom_theme Custom Custom
```
```$ npm run build-css```
Which will create a new custom_theme from a parent bs_bootstrap theme.
Which will download all dependencies and build CSS files.
### Standard stuff
Build CSS with
In your custom theme execute next commands:
Download all dependencies and build CSS files.
```
$ npm run build-css
```
Build CSS with
```
$ npx gulp sass
```
Use watch task if you like
```
$ npx gulp watch
```
Just build everything for production
```
$ npx gulp
```
......@@ -110,7 +120,7 @@ Specific Gulp task we currently offers are:
- npx gulp sass:lint
- npx gulp clean:css
Additionally bs_bootstrap child theme offers next two tasks:
Additionally, bs_bootstrap child theme offers next two tasks:
- npx gulp bootstrap:js
- npx gulp bootstrap:js:dev
......
......@@ -195,3 +195,57 @@ function bs_base_bs_update_8009($target_theme_name) {
]);
}
}
/**
* Update node js packages.
*/
function bs_base_bs_update_8010($target_theme_name) {
$themes_info = _bs_base_drupal_theme_list_info();
if (isset($themes_info[$target_theme_name])) {
// Dependency update.
$updates = [
'"autoprefixer": ".*"' => "\"@hail2u/css-mqpacker\": \"github:hail2u/node-css-mqpacker#v9.0.1\",\n \"autoprefixer\": \"^10.4.13\"",
// Remove css-mqpacker in favor on new @hail2u/css-mqpacker.
'^\s*"css-mqpacker": ".*",\n' => '',
'"bootstrap": ".*"' => '"bootstrap": "~4.6.2"',
'"gulp-load-plugins": ".*"' => '"gulp-load-plugins": "^2.0.8"',
'"gulp-sass": ".*"' => '"gulp-sass": "^5.1.0"',
'"postcss": ".*"' => "\"node-sass\": \"^8.0.0\",\n \"postcss\": \"^8.4.21\"",
'"stylelint": ".*"' => '"stylelint": "^14.16.1"',
'"stylelint-config-standard": ".*"' => '"stylelint-config-standard": "^29.0.0"',
'"stylelint-order": ".*"' => '"stylelint-order": "^6.0.1"',
'"stylelint-scss": ".*"' => '"stylelint-scss": "^4.3.0"',
];
// If node is already defined just update to version 18.
if (_bs_base_regexp_exist($themes_info[$target_theme_name]->subpath . '/package.json', '"node": ".*"')) {
$updates['"node": ".*"'] = '"node": "18"';
}
else {
$updates['"license": "GPL",'] = "\"license\": \"GPL\",\n \"engines\": {\n \"node\": \"18\"\n },";
}
_bs_base_regexp_file($themes_info[$target_theme_name]->subpath . '/package.json', $updates);
// gulp-sass 5 breaking change.
_bs_base_regexp_file($themes_info[$target_theme_name]->subpath . '/gulp-tasks.js', [
'\(gulp, plugins, options\)' => '(gulp, sass, plugins, options)',
]);
_bs_base_regexp_file($themes_info[$target_theme_name]->subpath . '/gulpfile.js', [
'merge = require\(\'deepmerge\'\);' => "merge = require('deepmerge');\nconst sass = require('gulp-sass')(require('node-sass'));",
'\(gulp, plugins, options\)' => '(gulp, sass, plugins, options)'
]);
// Copy new .npmrc and .nvmrc from bs_bootstrap theme.
$options = [
'parent_machine_name' => 'bs_bootstrap',
'parent_path' => _bs_base_drupal_get_theme_path('bs_bootstrap'),
'child_machine_name' => $target_theme_name,
'child_path' => _bs_base_drupal_get_theme_path($target_theme_name),
];
foreach (['.npmrc', '.nvmrc'] as $file) {
_bs_base_copy_file($file, $options);
}
// Remove node_modules so, we are sure we install/rebuild everything clean.
system('rm -rf ' . escapeshellarg($themes_info[$target_theme_name]->subpath . '/node_modules'));
}
}
......@@ -123,7 +123,7 @@ function drush_bs_base_bs_theme_create($parent_machine_name, $child_machine_name
_bs_base_reconfigure_theme_files($options);
// Copy theme-options.yml from parent theme. Try first to copy template if it
// exist, if not copy theme-options.yml.
// exists, if not copy theme-options.yml.
$theme_options_filename = FALSE;
if (file_exists($options['parent_path'] . '/template.theme-options.yml')) {
$theme_options_filename = 'template.theme-options.yml';
......@@ -303,7 +303,7 @@ function _bs_base_array_unique_lines(array $lines) {
if (strpos($line, '//') !== 0) {
$comment_line = '//' . $line;
if (in_array($comment_line, $lines)) {
// If it exist we will save commented version.
// If it exists we will save commented version.
$unique_lines[] = $comment_line;
continue;
}
......@@ -341,8 +341,10 @@ function _bs_base_copy_theme_files(array $options) {
'config/schema',
'templates',
'templates/README.md',
'.gitignore',
'.browserslistrc',
'.gitignore',
'.npmrc',
'.nvmrc',
'favicon.ico',
'gulp-tasks.js',
'gulpfile.js',
......@@ -362,8 +364,8 @@ function _bs_base_copy_theme_files(array $options) {
*
* If parent file is a directory then it will be created.
*
* Target sub-directories of a file will be created automatically if they do not
* exists.
* Target subdirectories of a file will be created automatically if they do not
* exist.
*
* @param string $file
* File name.
......@@ -398,7 +400,7 @@ function _bs_base_copy_file($file, array $options) {
}
// In the case when file name has directory in it make sure that all
// sub-directories exists in target before doing actual file copy.
// subdirectories exists in target before doing actual file copy.
if (!_bs_base_ensure_directory($new_file_name, $options['child_path'])) {
return FALSE;
}
......@@ -421,7 +423,7 @@ function _bs_base_copy_file($file, array $options) {
* The name of the theme whose base we are looking for.
*
* @return array
* Returns an array of all of the theme's ancestors including specified theme.
* Returns an array of all the theme's ancestors including specified theme.
*/
function _bs_base_drupal_get_base_themes(array $themes, $theme) {
$base_themes = [$theme => $themes[$theme]->info['name']];
......@@ -603,7 +605,7 @@ function _bs_base_drupal_scan_directory($dir) {
$extension->type = $type;
$extension->pathname = $pathname;
$extension->filename = $filename;
// Add dir to subpath so we can work with multisites also.
// Add dir to subpath, so we can work with multisites also.
$extension->subpath = (!empty($dir) ? $dir . '/' : '') . $fileinfo->getSubPath();
// Extension parent folder path.
$extension->parentPath = substr($fileinfo->getPath(), 0, -(strlen($name) + 1));
......@@ -646,7 +648,7 @@ function _bs_base_drupal_theme_list_info($reset = FALSE) {
* The machine name of the theme whose parent themes we are looking for.
*
* @return array
* Returns an array of all of the parent themes.
* Returns an array of all the parent themes.
*/
function _bs_base_get_parent_themes($theme_machine_name) {
$all_themes = _bs_base_drupal_theme_list_info();
......@@ -1434,6 +1436,23 @@ function _bs_base_get_sass_files($path) {
return $files;
}
/**
* Wraps a regexp pattern.
*
* @param $pattern
* Regexp pattern.
* @param string $modifiers
* PHP regular expression modifiers.
* @param string $delimiter
* PHP regular expression delimiter.
*
* @return string
* Wrapped regexp pattern.
*/
function _bs_base_get_regexp($pattern, string $modifiers = 'm', string $delimiter = '%'): string {
return $delimiter . $pattern . $delimiter . $modifiers;
}
/**
* Regular expression search and replace in the text.
*
......@@ -1449,10 +1468,11 @@ function _bs_base_get_sass_files($path) {
* @return string
* Replaced text.
*/
function _bs_base_regexp($text, array $regexps, $modifiers = 'm', $delimiter = '%') {
function _bs_base_regexp(string $text, array $regexps, string $modifiers = 'm', string $delimiter = '%'): string
{
$new_content = $text;
foreach ($regexps as $pattern => $value) {
if ($replaced = preg_replace($delimiter . $pattern . $delimiter . $modifiers, $value, $new_content)) {
if ($replaced = preg_replace(_bs_base_get_regexp($pattern, $modifiers, $delimiter), $value, $new_content)) {
$new_content = $replaced;
}
}
......@@ -1461,7 +1481,7 @@ function _bs_base_regexp($text, array $regexps, $modifiers = 'm', $delimiter = '
}
/**
* Regular expression search and replace in the file.
* Checks if file content matches against a regular expression.
*
* @param string $file_name
* File path.
......@@ -1481,13 +1501,35 @@ function _bs_base_regexp_file($file_name, array $regexps) {
return file_put_contents($file_name, _bs_base_regexp($file_contents, $regexps));
}
/**
* Regular expression exist in the file.
*
* @param string $file_name
* File path.
* @param string $regexp
* Array of regexps searches with it replace values.
*
* @return bool
* TRUE if it exists, FALSE other way.
*/
function _bs_base_regexp_exist($file_name, $pattern) {
$file_contents = file_get_contents($file_name);
if ($file_contents === FALSE) {
drush_log("Can not open file $file_name for regexp search&replace.", LogLevel::WARNING);
return FALSE;
}
$matches = [];
return preg_match(_bs_base_get_regexp($pattern), $file_contents, $matches) === 1;
}
/**
* Set primitive values in a yml file.
*
* Please note that this implementation is not perfect but exist only to support
* the needs of this drush implementation. There are couple of limitations that
* are explained in function comments. Most importantly values in values array
* can be only primitive types for now.
* the needs of this drush implementation. There are a couple of limitations
* that are explained in function comments. Most importantly values in values
* array can be only primitive types for now.
*
* @param string $path
* Yaml file path.
......
......@@ -3,13 +3,13 @@
# Child themes will inherit this options.
#
# List of gulp plugins from package.json which we are lazy auto loading.
# List of gulp plugins from package.json which we are lazy autoload.
gulpPlugins:
pattern:
- "gulp-*"
- "gulp.*"
- "autoprefixer"
- "css-mqpacker"
- "@hail2u/css-mqpacker"
- "del"
- "postcss-*"
- "stylelint"
......@@ -17,10 +17,8 @@ gulpPlugins:
- "through2"
# Rename mapping to values that we will use in JS code.
rename:
css-mqpacker: "mqpacker"
postcss-reporter: "reporter"
postcss-scss: "syntax_scss"
gulp-sass-glob: "sassGlob"
gulp-sass-inject: "sassInject"
through2: "through"
......
// Define gulp tasks.
module.exports = function (gulp, plugins, options) {
module.exports = function (gulp, sass, plugins, options) {
'use strict';
var fs = require('fs');
const fs = require('fs');
// Processor for linting is assigned to options so it can be reused later.
// Processor for linting is assigned to options, so it can be reused later.
options.processors = [
// Options are defined in .stylelintrc.yaml file.
plugins.stylelint(options.stylelint),
......@@ -15,12 +15,12 @@ module.exports = function (gulp, plugins, options) {
// Post CSS options.
options.postcssOptions = [
plugins.autoprefixer(options.autoprefixer),
plugins.mqpacker({sort: true})
plugins.hail2u.cssMqpacker({sort: true})
];
// Defining gulp tasks.
// Load theme _functions.scss partial if it exist so we can use them
// Load theme _functions.scss partial if it exists, so we can use them
// in theme-options.yml.
// Clone themes array from parentTheme and add current theme because we need
// to check it also.
......@@ -43,11 +43,11 @@ module.exports = function (gulp, plugins, options) {
}
gulp.task('sass', function () {
var task = gulp.src(options.sass.src + '/**/*.scss');
const task = gulp.src(options.sass.src + '/**/*.scss');
task.pipe(plugins.sassInject(options.sass.injectVariables))
.pipe(plugins.through.obj(loadFunctions))
.pipe(plugins.sass({
.pipe(sass({
outputStyle: 'expanded',
includePaths: options.sass.includePaths
}))
......@@ -58,10 +58,10 @@ module.exports = function (gulp, plugins, options) {
});
gulp.task('sass:dev', function () {
var task = gulp.src(options.sass.src + '/**/*.scss', {sourcemaps: true});
const task = gulp.src(options.sass.src + '/**/*.scss', {sourcemaps: true});
task.pipe(plugins.sassInject(options.sass.injectVariables))
.pipe(plugins.through.obj(loadFunctions))
.pipe(plugins.sass({
.pipe(sass({
outputStyle: 'expanded',
includePaths: options.sass.includePaths,
}))
......
......@@ -6,17 +6,18 @@
'use strict';
// Load gulp and needed lower level libs.
var gulp = require('gulp');
var yaml = require('js-yaml');
var fs = require('fs');
const gulp = require('gulp');
const yaml = require('js-yaml');
const fs = require('fs');
const sass = require('gulp-sass')(require('node-sass'));
// Load gulp options.
var options = yaml.load(fs.readFileSync('./gulp-options.yml', 'utf8'));
let options = yaml.load(fs.readFileSync('./gulp-options.yml', 'utf8'));
// Lazy load gulp plugins.
// By default gulp-load-plugins will only load "gulp-*" and "gulp.*" tasks,
// By default, gulp-load-plugins will only load "gulp-*" and "gulp.*" tasks,
// so we need to define additional patterns for other modules we are using.
var plugins = require('gulp-load-plugins')(options.gulpPlugins);
const plugins = require('gulp-load-plugins')(options.gulpPlugins);
// Load gulp tasks.
require('./gulp-tasks.js')(gulp, plugins, options);
require('./gulp-tasks.js')(gulp, sass, plugins, options);
......@@ -3,9 +3,12 @@
"description": "BS Base theme",
"private": true,
"license": "GPL",
"engines" : {
"node" : "18"
},
"devDependencies": {
"@hail2u/css-mqpacker": "github:hail2u/node-css-mqpacker#v9.0.1",
"autoprefixer": "^10.4.5",
"css-mqpacker": "^7.0.0",
"deepmerge": "^4.2.2",
"del": "^6.0.0",
"font-awesome": "^4.7.0",
......@@ -15,17 +18,18 @@
"gulp-load-plugins": "^2.0.7",
"gulp-plumber": "^1.2.1",
"gulp-postcss": "^9.0.1",
"gulp-sass": "^4.1.1",
"gulp-sass": "^5.1.0",
"gulp-sass-inject": "^1.1.1",
"gulp-sass-lint": "^1.4.0",
"gulp-strip-css-comments": "^2.0.0",
"js-yaml": "^4.1.0",
"node-sass": "^8.0.0",
"postcss": "^8.4.13",
"postcss-reporter": "^7.0.5",
"stylelint": "^13.13.1",
"stylelint-config-standard": "^22.0.0",
"stylelint-order": "^4.1.0",
"stylelint-scss": "^3.21.0",
"stylelint": "^14.16.1",
"stylelint-config-standard": "^29.0.0",
"stylelint-order": "^6.0.1",
"stylelint-scss": "^4.3.0",
"stylelint-selector-bem-pattern": "^2.1.1",
"through2": "^4.0.2"
},
......
This diff is collapsed.
engine-strict=true
18
......@@ -5,7 +5,7 @@ base theme: bs_base
core_version_requirement: ^9.3 || ^10
bs_versions:
bs_base: 8008
bs_base: 8010
# @todo - Core does not allow for now themes to declare dependencies on modules.
# @see https://www.drupal.org/project/drupal/issues/474684
......
......@@ -385,7 +385,7 @@ hr {
small,
.small {
font-size: 80%;
font-size: 0.875em;
font-weight: 400;
}
......@@ -425,7 +425,7 @@ mark,
.blockquote-footer {
display: block;
font-size: 80%;
font-size: 0.875em;
color: #6c757d;
}
......
......@@ -17,6 +17,12 @@
transition: height 0.35s ease;
}
.collapsing.width {
width: 0;
height: auto;
transition: width 0.35s ease;
}
@media (prefers-reduced-motion: reduce) {
.fade {
transition: none;
......@@ -24,4 +30,7 @@
.collapsing {
transition: none;
}
.collapsing.width {
transition: none;
}
}
......@@ -6,7 +6,6 @@
vertical-align: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
......
......@@ -46,10 +46,6 @@
background-color: #f2f2f2;
}
.form--floating-labels--filled .form-group--floating-label textarea.form-control:not(:-ms-input-placeholder) ~ label {
background-color: #f2f2f2;
}
.form--floating-labels--filled .form-group--floating-label textarea.form-control:not(:placeholder-shown) ~ label, .form--floating-labels--filled .form-group--floating-label textarea.form-control:not([placeholder=' ']) ~ label {
background-color: #f2f2f2;
}
......
......@@ -33,11 +33,6 @@
padding-bottom: 0.5rem;
}
.form--floating-labels--outlined .form-group--floating-label .form-control:not(:-ms-input-placeholder):not(textarea) {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}
.form--floating-labels--outlined .form-group--floating-label .form-control:not(:placeholder-shown):not(textarea), .form--floating-labels--outlined .form-group--floating-label .form-control:not([placeholder=' ']):not(textarea), .form--floating-labels--outlined .form-group--floating-label .form-control:focus:not(textarea) {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
......@@ -47,10 +42,6 @@
transform: translateY(-50%);
}
.form--floating-labels--outlined .form-group--floating-label .form-control:not(:-ms-input-placeholder) ~ label {
transform: translateY(-50%);
}
.form--floating-labels--outlined .form-group--floating-label .form-control:not(:placeholder-shown) ~ label, .form--floating-labels--outlined .form-group--floating-label .form-control:not([placeholder=' ']) ~ label, .form--floating-labels--outlined .form-group--floating-label .form-control:focus ~ label {
transform: translateY(-50%);
}
......
......@@ -124,10 +124,6 @@ label,
padding-bottom: 0.5rem;
}
.form-group--floating-label textarea.form-control:not(:-ms-input-placeholder) {
padding-bottom: 0.5rem;
}
.form-group--floating-label textarea.form-control:not(:placeholder-shown), .form-group--floating-label textarea.form-control:not([placeholder=' ']), .form-group--floating-label textarea.form-control:focus {
padding-bottom: 0.5rem;
}
......@@ -137,11 +133,6 @@ label,
background-color: #fff;
}
.form-group--floating-label textarea.form-control:not(:-ms-input-placeholder) ~ label {
padding-top: 0.25rem;
background-color: #fff;
}
.form-group--floating-label textarea.form-control:not(:placeholder-shown) ~ label, .form-group--floating-label textarea.form-control:not([placeholder=' ']) ~ label, .form-group--floating-label textarea.form-control:focus ~ label {
padding-top: 0.25rem;
background-color: #fff;
......
......@@ -32,11 +32,6 @@
opacity: 1;
}
.form-control:-ms-input-placeholder {
color: #6c757d;
opacity: 1;
}
.form-control::placeholder {
color: #6c757d;
opacity: 1;
......@@ -197,7 +192,7 @@ textarea.form-control {
display: none;
width: 100%;
margin-top: 0.3rem;
font-size: 80%;
font-size: 0.875em;
color: #28a745;
}
......@@ -308,7 +303,7 @@ textarea.form-control {
display: none;
width: 100%;
margin-top: 0.3rem;
font-size: 80%;
font-size: 0.875em;
color: #dc3545;
}
......@@ -432,7 +427,7 @@ textarea.form-control {
min-height: 1.6875rem;
padding-left: 1.5rem;
-webkit-print-color-adjust: exact;
color-adjust: exact;
print-color-adjust: exact;
}
.custom-control-inline {
......@@ -493,7 +488,7 @@ textarea.form-control {
pointer-events: none;
content: "";
background-color: #fff;
border: #adb5bd solid 1px;
border: 1px solid #adb5bd;
}
.custom-control-label::after {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment