SASS/SCSS support
DomUI supports Sass in SCSS format out of the box (since 2.0). The new 2.0 stylesheet (winter) is a scss stylesheet. These stylesheets are compiled on-the-fly by the DomUI server code, so changes made to the stylesheets take effect immediately.
Parameter support
SASS uses variables and has quite advanced control structures. In DomUI it is possible to pass variables from "outside" the stylesheet into it. This allows you to control parts of the stylesheet's content depending on these variables.
To use the variables passed from the DomUI server the stylesheet must use
@import "_parameters"
This fixed name is not a real file (even though it might exist on the file system somewhere) but its content are generated by the DomUI server on the fly, and it contains variable assignments controlled by the framework.
There are two ways to control what variables are present in that file: URL parameters and session parameters.
Variables from URL parameters
The URL for the scss stylesheet can contain URL parameters. These parameters will be converted to SASS variables using the following mechanism:
- Any URL parameter whose name ends in $ is assumed to be a string variable, and the string value of the parameter will be added as a string to the generated _parameter.scss file. For example, if you add:
&header$=bg1.png
the parameter file will contain
$header="bg1.png";
i.e. the dollar sign is removed from the name, and the parameter value is quoted. - Any other parameter will be added verbatim, i.e. if you add:
&xmas=true
you will get the following inside the parameter file:
$xmas=true;
When creating the URL you need to take care of proper URL escaping of the values and names for the URL inside the HTML generated. This means that the dollar sign needs to be escaped as %24, and any oddities in the values need to be escaped like that too.
Caching and parameters
Stylesheets are cached inside the server for performance. Adding parameters means that each set of parameters requires a new sass compile and a new entry in the cache, so don't do things like adding a unique parameter per user. The "key" for a cached stylesheet is the complete URL including all parameters and their values.
Implementation
The Sass stylesheets are handled by SassPartFactory: a buffered Part factory. This factory recognizes both .scss and .sass files. Since this is a buffered part factory all scss files compiled through it are cached in memory.Internals
The actual compilation is done by asking the SassCompilerFactory for a compiler. New compiler implementations can be built and registered there. We currently have two implementations:
- The jsass compiler, which uses the Java JSass wrapper to the libsass native library. This is the default compiler as it is up-to-date with the standards. The disadvantage is that this compiler might not be available on all platforms, and it might need a custom installation.
- The Vaadin Sass compiler, part of the Vaadin framework. This is a Java native compiler but has quite a few bugs and does not support the latest standards fully. Development seems to have stopped: the last commit was from 2015.
The jsass compiler will be used unless the code finds out that it is not available, in which case it will fall back to the vaadin compiler. This of course might make your files not compile.
Some Sass/SCSS pitfalls
I had some fun getting up to speed with sass. Here are some things important to know.
What the fsck are partials?
Existing Sass compilers will "watch" a directory of files, and will compile all files that end in ".sass" or ".scss" to the equivalent .css file as soon as a file changes or appears.
This is nice, except when files are only meant to be @import ed: those files should not be compiled to .css as they are meant to be part of another file. To prevent that you name the file with a starting underscore: this tells those other compilers that the file is not to be translated at all.
For DomUI this has no real meaning as it only reads the sass files that are requested and translates those on the fly. But we keep the convention because it allows you to also statically translate the sass files used in DomUI and just use the resulting css.
So: partials have no meaning at all in the compilation process: they are just files to be imported.
What does @import do
Import is confusing: it is actually what other languages call include: the source mentioned in the import is "copied" in the file doing the import at the location OF the import. So the following two files:
_file1.scss:
position: absolute;
file2.scss:
@import "file1"; @import "file1"; @import "file1";
will result in
position: absolute; position: absolute; position: absolute;
At the same time tools like IntelliJ complain when you use variables, mixins or functions that are defined in some other file: it tells you that the variable is guessed from files and that en import is needed.
To fix this you should do the following:
- Move all non-code producing things, like variables, functions, mixins and whatnot to separate fragments
- @import those fragments every time they are needed in some other fragment.