Integrated scss style building in Grunt extension

This commit is contained in:
PMKuipers 2023-08-26 23:37:36 +02:00
parent 413f5c3e4f
commit 64f9b8b043
9 changed files with 2299 additions and 793 deletions

101
Gruntfile.js Normal file
View File

@ -0,0 +1,101 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* Grunt configuration for local_treestudyplan
*
* @copyright 2023 P.M. Kuipers
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Grunt configuration.
*
* @param {Grunt} grunt
*/
module.exports = function(grunt) {
const path = require('path');
const process = require('process');
const sass = require('sass');
// Import grunt configuration for moodle base
process.chdir("../.."); // change dir to moodle base
require(path.resolve(`./Gruntfile.js`))(grunt); // Run Gruntfile module from moodle base
grunt.registerTask('scssplugin','Compile scss/*.sccs into styles.css and css/devstyles.css', () => {
const devoutput = 'css/devstyles.css';
const prodoutput = 'styles.css';
// Get full path of compenent and scss folder
const componentPath = path.join(grunt.moodleEnv.gruntFilePath,grunt.moodleEnv.componentDirectory);
const scssPath = path.join(componentPath, 'scss','styles.scss');
console.log(`Compiling ${scssPath} including any imported files therein`);
process.chdir(path.join(componentPath, 'scss'));
const result = sass.compile(scssPath);
if ( result ) {
console.info("got result");
// Some regex processing to match moodle stylelint styles
// change tab indent to 4 instead of 2
let css = result.css.replace(/^ ([^ ])/gm ," $1");
// insert a newline after every comma in a css selector
// (only combined selectors will get that long)
css = css.replace(/^[^ ].*[\{,]$/gm , (m) => { // Find CSS selector lines
return m.replace(/, /g,",\n"); // replace comma followed by space with comma newline
});
// replace hex color codes with lowercase (convenience function since I don't really care for the hex codes lowercase only rule)
const hexCodeToLower = (match, m1, m2) => {
return '#'+m1.toLowerCase()+m2;
}
css = css.replace(/#([A-F0-9a-f]{3})([^A-F0-9a-f]?)/gm , hexCodeToLower); // 3 digit color codes
css = css.replace(/#([A-F0-9a-f]{6})([^A-F0-9a-f]?)/gm , hexCodeToLower); // 6 digit color codes
css = css.replace(/#([A-F0-9a-f]{8})([^A-F0-9a-f]?)/gm , hexCodeToLower); // 8 digit color codes (with alpha)
// All other errors should really be fixed in the scss files :)
[devoutput,prodoutput].forEach((output) => {
console.info(`Storing ${output}`);
grunt.file.write(path.join(componentPath, output),css);
});
}
});
// Rebuild on changes in the scss files when using 'grunt watch'
grunt.config.merge({
watch: {
scssplugin: {
files: ['scss/*.scss'],
tasks: ['scssplugin']
},
},
});
// Remove gherkinlint from the startup list, since it exits with an error because of errors in moodle's own code
grunt.moodleEnv.startupTasks.splice(grunt.moodleEnv.startupTasks.indexOf("gherkinlint"),1);
// Add the 'scssplugin' task as a startup task.
grunt.moodleEnv.startupTasks.push('scssplugin');
};

View File

@ -14,6 +14,7 @@ $SCRIPTDIR/vuemode.sh prod
# so we can be sure all javascript is properly built from the most recent source
cd $SCRIPTDIR
grunt amd
grunt scssplugin # plugin specific scss task to compile styles.css from scss files
# run the build php script
php ${SCRIPTDIR}/build.php $@

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
.path-local-treestudyplan {
div.tab-pane:target {
margin-top: 0px;
margin-top: 0;
}
[v-cloak] {
@ -12,4 +12,8 @@
margin: auto;
}
.special {
color: gold;
}
}

View File

@ -5,16 +5,16 @@ quite hard to maintain.
Unfortunately, moodle does not extend the sass/scss compiler support to plugins
that are not a theme.
To alleviate this, this plugin includes it's own scss compiler script that compiles
all scss files in this directory into one css file - css/devstyles.css
To alleviate this, this plugin extends moodle's Gruntfile.js scripts
to compile 'scss/styles.scss' into 'css/devstyles.css' (and 'styles.css')
This files is used instead of styles.css in order to avoid having to clear the theme
'css/devstyles.css' is used instead of styles.css in order to avoid having to clear the theme
cache every time a style rule is changed during development.
Once I devise a method to use styles.css in production environtments and css/devstyles.css
production environments, the compiler will compile it into both css/devstyles.css
and styles.css
Call the plugin's scss compiler by running scssbuild.sh in the plugin's root.
The grunt command to compile is 'grunt scssplugin'

View File

@ -71,7 +71,7 @@
display: grid;
grid-auto-flow: column;
/*border-bottom-style: solid;*/
border-color: #cccccc;
border-color: #ccc;
border-width: 1px;
}
@ -91,7 +91,7 @@
.t-studyline .t-studyline-editmode-content {
border-right-style: solid;
border-color: #cccccc;
border-color: #ccc;
border-width: 1px;
}
@ -233,19 +233,19 @@
.t-studyline-slot.t-studyline-slot-0 .t-slot-drop.filter .t-slot-item,
.r-studyline-slot.r-studyline-slot-0 .r-item-base {
margin-left: 0px;
margin-left: 0;
}
.t-studyline-slot.gradable.current.odd,
.r-studyline-slot.gradable.current.odd {
--hlcol: color-mix(in srgb, var(--less-light) , var(--highlight) var(--highlight-mix));
--hlcol: color-mix(in srgb, var(--less-light), var(--highlight) var(--highlight-mix));
background-color: var(--hlcol);
position: relative;
}
.t-studyline-slot.gradable.current.odd:before,
.r-studyline-slot.gradable.current.odd:before {
--hlcol: color-mix(in srgb, var(--less-light) , var(--highlight) var(--highlight-mix));
--hlcol: color-mix(in srgb, var(--less-light), var(--highlight) var(--highlight-mix));
box-shadow: -20px 0 10px -7px var(--hlcol) inset;
content: " ";
height: 100%;
@ -257,7 +257,7 @@
.t-studyline-slot.gradable.current.odd:after,
.r-studyline-slot.gradable.current.odd:after {
--hlcol: color-mix(in srgb, var(--less-light) , var(--highlight) var(--highlight-mix));
--hlcol: color-mix(in srgb, var(--less-light), var(--highlight) var(--highlight-mix));
box-shadow: 20px 0 10px -7px var(--hlcol) inset;
content: " ";
height: 100%;
@ -272,7 +272,7 @@
}
.s-studyline-header-period.current {
--hlcol: color-mix(in srgb, var(--white) , var(--highlight) var(--highlight-mix));
--hlcol: color-mix(in srgb, var(--white), var(--highlight) var(--highlight-mix));
box-shadow: 0 0 10px 10px var(--hlcol);
background-color: var(--hlcol);
border-top-left-radius: 16px;
@ -285,14 +285,14 @@
.t-studyline-slot.gradable.current.even,
.r-studyline-slot.gradable.current.even {
--hlcol: color-mix(in srgb, var(--white) , var(--highlight) var(--highlight-mix));
--hlcol: color-mix(in srgb, var(--white), var(--highlight) var(--highlight-mix));
background-color: var(--hlcol);
position: relative;
}
.t-studyline-slot.gradable.current.even:before,
.r-studyline-slot.gradable.current.even:before {
--hlcol: color-mix(in srgb, var(--white) , var(--highlight) var(--highlight-mix));
--hlcol: color-mix(in srgb, var(--white), var(--highlight) var(--highlight-mix));
box-shadow: -20px 0 10px -7px var(--hlcol) inset;
content: " ";
height: 100%;
@ -308,7 +308,7 @@
.t-studyline-slot.gradable.current.even:after,
.r-studyline-slot.gradable.current.even:after {
--hlcol: color-mix(in srgb, var(--white) , var(--highlight) var(--highlight-mix));
--hlcol: color-mix(in srgb, var(--white), var(--highlight) var(--highlight-mix));
box-shadow: 20px 0 10px -7px var(--hlcol) inset;
content: " ";
height: 100%;
@ -361,7 +361,7 @@
.t-item-deletebox.drop-in {
visibility: visible;
border-style: solid;
background-color: #FFCCCC;
background-color: #FCC;
color: #a00;
}
@ -401,7 +401,7 @@
position: absolute;
top: calc(50% - 5px);
right: -1px;
line-height: 0px;
line-height: 0;
}
.t-item-connector-start svg rect {
@ -421,7 +421,7 @@
top: 50%;
transform: translate(0, -50%);
left: -1px;
line-height: 0px;
line-height: 0;
}
.t-item-connector-end svg rect {
@ -458,7 +458,7 @@
position: absolute;
left: 50%;
transform: translate(-50%, 100%);
bottom: 0px;
bottom: 0;
z-index: 25;
}
@ -474,7 +474,7 @@
.t-item-filter {
display: inline-block;
height: 1em;
padding: 0px;
padding: 0;
margin: 0;
text-align: left;
font-size: 2em;
@ -545,7 +545,7 @@
a.t-item-course-config {
font-size: 16pt;
font-size: 21px /*16pt*/;
vertical-align: middle;
float: right;
margin-right: 2px;
@ -698,7 +698,7 @@
.r-item-filter {
display: inline-block;
padding: 0px;
padding: 0;
text-align: left;
font-size: 2em;
vertical-align: top;
@ -799,14 +799,14 @@
}
.r-course-grading {
font-size: 16pt;
font-size: 21px /*16pt*/;
margin-right: 2px;
vertical-align: bottom;
}
.r-course-graded,
.r-course-result {
font-size: 16pt;
font-size: 21px /*16pt*/;
vertical-align: middle;
float: right;
margin-right: 2px;
@ -819,7 +819,7 @@
}
.r-completion-detail-header {
font-size: 20pt;
font-size: 26px /*20pt*/;
}
.r-item-finish.completion-incomplete,
@ -1019,7 +1019,7 @@
}
.s-studyplan-card-title-buttons {
font-size: 12pt;
font-size: 16px /*12pt*/;
float: right;
}
.s-studyplan-card-title-buttons > * {
@ -1115,9 +1115,14 @@
margin-right: 1em;
}
.s-edit-mod-form [data-fieldtype=submit] { display: none ! important; }
.s-edit-mod-form.genericonly form > fieldset:not(#id_general) { display: none ! important; }
.s-edit-mod-form [data-fieldtype=submit] {
/* if not working, make selector more specific */
display: none;
}
.s-edit-mod-form.genericonly form > fieldset:not(#id_general) {
/* if not working, make selector more specific */
display: none;
}
.border-grey {
border-color: #aaa;
}

4
scss/styles.scss Normal file
View File

@ -0,0 +1,4 @@
@import "colors.scss";
@import "generic.scss";
@import "invitemanager.scss";
@import "studyplan.scss"

View File

@ -1,63 +0,0 @@
#!/usr/bin/env node
// This file is part of the Studyplan plugin for Moodle
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
/**
* This file compiles the scss files in the scss/ folder into either the main
* styles.css for production upon build or css/devstyles.css for development
*
* Most nice would be to integrate this action with grunt watch, but I am
* not familiar enough with grunt to know if I can extend moodle's grunt actions
* from a Gruntfile.js in this directory without modifying Moodle's Gruntfile.js
*
* @package local_treestudyplan
* @copyright 2023 P.M. Kuipers
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
const sass = require('sass');
const path = require('path');
const fs = require('fs');
const output = 'css/devstyles.css';
let css = "";
let map = "";
//joining path of directory
const directoryPath = path.join(__dirname, 'scss');
//passsing directoryPath and callback function
fs.readdir(directoryPath, function (err, files) {
//handling error
if (err) {
return console.log('Unable to scan directory: ' + err);
}
//listing all files using forEach
files.forEach(function (file) {
if (file.endsWith(".scss")) {
const result = sass.compile(file);
console.info(`Processing ${file}...`)
if ( result ) {
css = css + `/**** ${file} ****/\n` + result.css + "\n";
}
}
});
console.info(`Storing ${output}`);
fs.writeFile(path.join(__dirname, output),css,(err) => {
if (err) throw err;
});
});

1274
styles.css

File diff suppressed because it is too large Load Diff