Today we're marking the completion of the biggest Libsass release to date!
The core developer team kept the pace high fixing a ton of open issues, while also refactoring large amounts of code, implementing a handful of new major features, and even some performance improvements to boot!
The sheer amount of features, fixes and refactors introduced quite a few regressions delaying this release. We want to thank all the people that reported issues, patches or contributed in any other form, that made this release happen 👏
By the numbers
- 108 closed issues
- 357+ new sass specs (including new output type)
- 1.047+ new assertions
- 8% increase in code coverage
Major new features
Output styles
The way Libsass outputs the final css was refactored to make the code more modular. This allowed us to add the missing compact and expanded output styles. This refactor also allows us to produce more accurate nested and compressed output styles (@mgreter, #910).
We updated our spec suite to support all output styles which added nearly 3,400 runs and 10,000 new assertions.
Strings and interpolation
String and interpolation parsing and evaluating was refactored too, which brings Libsass even closer to Ruby Sass in terms of output styles now (@mgreter, #847).
Sourcemaps
The refactoring work on strings, interpolations and output styles made it a lot easier to guarantee the correctness of the generated sourcemap files (@mgreter, #879)
Directive bubbling
@media
, @supports
, @keyframes
directives (and more!) are correctly bubbled so you always get CSS 2.0 compliant output.
This means @media
rules will be "combined" with all bubbled up @media
rules to better reflect the Ruby Sass behaviour (@xyfer, #800, #821).
@at-root
Full support for the @at-root
directive has been implemented (@xyfer, #799, #859).
&
in SassScript
Partial support for &
in SassScript (@ekskimn, #966, #548)
&
can now be used a css property or passed as an argument to functions and mixins.
Variable scope
Full support for !global
variable scoping has been implemented (@mgreter, #986, #990)
New experimental feature
This release contains initial (and experimental) support to load 3rd party plugins in the form of precompiled .dll
(win) or .so
(nix) files. We really would like to see some people playing around with this new toy. It could help us determine what we actually want to do with this technology! (@mgreter, #919)
Breaking changes
- Change in
sass_make_data_context
- libsass now really takes memory ownership (#925) - Hard deprecated
image-url
andcompact
functions (throw errors until removed) (#834, #835)
Changes in C-API
- Implement error status for importer entries (#926)
- Breaking change in
sass_make_data_context
(#925) - Add
char* indent
andchar* linefeed
to options (#787) - Add
string_list* plugin_paths
to options (#919) - Add
char* plugin_path
to options (#919) - Add
char* source_map_root
to options (#926) - Add
char* error_text
to options (#915) - Add
sass_option_push_plugin_path
function (#919) - Remove
char* image_path
from options (#834) - A few source files have been added and some removed
Improved spec tests
Due to the new support for all output styles, the spec tests have been enhanced to test all four output styles. The tests are now much more white-space sensitive than before, as only multiple line-feeds are normalized. This should ensure that libsass gets and stays closer to the exact output of ruby sass in the future.
Minor features
- Implement raw css imports (@mgreter, #754, #318)
- Implement number prefix parsing (/[+-]+/) (@mgreter, #535)
- Improve source-mapping implementation (@mgreter, #792)
- Improve handling of negative numbers (@xyfer, #828)
- Add support for -ms-calc (@xyfer, #842)
- Add an example plugin (@mgreter, d3de957)
- Add Visual Studio file to .gitignore (@am11, #944)
- Fully evaluate nested binary operations (@xyfer, #770)
- Normalize CSS function string arguments (@xyfer, #817)
- Made linefeed and indent configurable (@mgreter, #787)
- Speed up Windows CI build times (@am11, #944)
- Update number function signatures (@xyfer, #826)
- Simplify autotools build (@saper, #992)
- Performance improvements in parser (@mgreter, #985, #990)
- Provide a formatted error output (@mgreter, #938)
- Add sass_context_take_included_files() (@rodneyrehm, #982)
- Support multiple importers (alpha, @mgreter, #1000, #962)
- Custom headers (experimental, @mgreter, #1000, #960)
- Implement /deep/ shadow DOM selector (@mgreter, #452)
- Enable
@extend
ing selector groups (@mgreter, #950) - Enable OS-X CI testing via Travis (@mgreter, #1024)
- Enable url function overloading (@mgreter, #1010, #674)
- Add
units-level-3
andat-error
feature flag (@xyfer, #1011, #1013)
Fixes
- Fix parsing of dash in declaration values (@xyfer, #733)
- Fix math operations sometimes returing wrong units (@xyfer, #783)
- Fix str-slice returning incorrect value when $end-at is omitted (@xyfer, #815)
- Fix arguments sometimes being passed by value not reference (@xyfer, #813, #909)
- Fix segfault if a function definition has a css comment (@xyfer, #646)
- Fix
@charset
not being output if utf8 characters are in top comment (@mgreter, #820) - Fix error message line numbers drifting with indented style (@anlutro, #866)
- Fix desaturation of greyscale colours (@anlutro, #864)
- Fix crash in Parser::parse_term (@mmaxim, #846)
- Fix greedy not operator (@xyfer, #873, #897, #920, #934)
- Fix function names not consistently normalized (@xyfer, #877)
- Fix color related issues in functions (@mgreter, #911)
- Fix dash parsing after other tokens (@mgreter, #922)
- Fix interpolation in media queries (@mgreter, #346)
- Fix comments on in propsets causing segfaults (@xzyfer, #901)
- Fix relative path issue on Window (@mgreter, #939)
- Fix relative path issue with Source Maps (@am11, #964)
- Fix memory management issues (@mgreter, #940)
- Fix block comment parsing regression (@mgreter, #941)
- Fix @error to exit with error message (@asottile, #967)
- Fix reported position when no token can be parsed (@mgreter, #972)
- Fix variable length parameter (@mgreter, #980)
- Fix regression with str-slice (@mgreter, #988)
- Fix allowing illegal extend error across media-queries (@mgreter, #943)
- Fix error parsing comments in propsets (@xyfer, #890)
- Fix error message line numbers drifting (@mgreter, #533, #972)
- Fix error on illegal parent selectors in root blocks (@mgreter, #325)
- Fix error on illegal media blocks extending (@mgreter, #317, #712)
- Fix error on multiline string with trailing backslash (@mgreter, #942)
- Fix error when property-value is missing (@mgreter, #945)
= Fix edge case in Parent_Selector evaluation (@mgreter, #1004) - Fix build to copy sass_version header (@drewwells, #998)
- Fix
&
interpolation causing segfaults (@mgreter, #978) - Fix wrong line in error message (@mgreter, #972)
- Fix variable Interpolation in @Keyframe (@mgreter, #947)
- Fix tabs when bubbling feature blocks (@mgreter, #1044)
- Fix white-space issue with wrapped selectors (@mgreter, #1025)
- Fix bug in C-API with context compiler status (@mgreter, #1038)
- Fix
@extend
specificity problems (@mgreter, #592) - Fix parsing of another missed block comment (@mgreter, #1021)
- Fix parsing of some more missed block commen (@mgreter, #1007)
- Fix dynamic exception as per C++11 specs. (@am11, #1006)
- Fix argument handling for dynamic
call
function (@mgreter, #1075) - Fix interpolation with unary expressions (@mgreter, #1074)
- Fix operator parsing regression (@mgreter, #1068)
- Fix backslash multiline string with win linefeed (@mgreter, #1067)
- Fix incorrect semantics of
@else
(@xyfer, #1062) - Fix source-map regression (@mgreter, #1056)
- Fix one regression with error reporting (@mgreter, #1054)
- Fix url parsing with trailing spaces in url (@mgreter, #1051)
- Fix
@elseif
keyword not being parsed (@xyfer, #1060) - Fix empty ruleset blocks sometimes being outputted (@mgreter, #1109 )
- Fix
random()
not always being random (@xzyfer, #1104) - Fix compilation errors on SmartOS (@candid @saper, #850)
- Fix map key handling (@mgreter, #1086)
- Fix errors parsing block comments in lists (@mgreter, #1082)
- Threadsafe
atof
implementation (@npiguet, #929) - Unquoting null should return null (@xyfer, #1106, #1124)
- Allow empty rest arguments in varargs (@mgreter, #1130)
- Fix the RGB to HSL algorithm (@xyfer, #1132)
- Fix call function incorrectly epanding map arguments (@xyfer, #1133)
- IE property hacks should be parsed as static values (@xyfer, #1098)
- Fix comment_to_string edge case (@xyfer, #1121)
- Fix various string handling regressions (@xyfer, #1127)
- Fix interpolation issues with escape sequence (@mgreter, #1115)
- Fix hsla argument overflow (@mgreter, #1101)
Known issues
- Still some @extends edge cases - (#1029, #1063, #1091)
- Interpolating
&
in selectors with@at-root
produces incorrect output - (#1043) - Interpolating
&
in attribute selectors doesn't work - (#1016)
Thanks!
A huge thanks to everyone who reported issues 🔆 !!
Honourable mentions to @am11, @anlutro, @asottile, @candid, @chriseppstein, @ekskimn, @hcatlin, @hugogiraudel, @lunelson, @mgreter, @mmaxim, @npiguet, @rodneyrehm, @saper, @Snugug and @xzyfer for their contributions to Libsass and Sass spec that made this release possible.
What's next?
With this release we've hit 97% feature parity with Ruby Sass according to sass-compatibility.github.io.
There are no signs of slowing down! We already have a bunch of features queued for 3.2.1.