Using PostCSS and PurgeCSS in Gulp - npm

I'm just trying to use PurgeCSS in the simpliest way I can imagine. But I can't even do that!
This code doesn't give any error, and it does create a new CSS file in the dest folder, so Gulp is processing the function. But the CSS resulting file has the same unused styles than the first one.
Tried with gulp-purgecss:
var gulp = require('gulp');
var purgecss = require('gulp-purgecss');
gulp.task('purgecss', function(){
return gulp.src('dist/css/styles.css')
.pipe(purgecss({
content: ['dist/**/*.html']
}))
.pipe(gulp.dest('min/css'));
});
And with PostCSS + PurgeCSS:
var gulp = require('gulp');
var postcss = require('gulp-postcss');
var postcsspurgecss = require('#fullhuman/postcss-purgecss');
gulp.task('postPurge', function(){
var postcssPlugins = [
postcsspurgecss({
content: ['**/*.html']
})
];
return gulp.src('dist/css/styles.css')
.pipe(postcss(postcssPlugins))
.pipe(gulp.dest('min/css'));
});
And actually, ideally I would like to use it with internal CSS. But any help with this standard approach would be much appreciated.
Thanks!

Related

How to compile a less file on demand?

I have an admin panel in which user selects some colors, and based on his choices, a colors.less file would be created in a specific directory.
Another file called styles.less imports colors.less.
I want to listen to colors.less and compile the styles.less whenever it's changed.
Is it possible? How can I do that?
One solution is to use GULP: https://gulpjs.com
This script watches the colors.less for changes and compiles the styles.less:
var gulp = require('gulp');
var gutil = require('gulp-util');
var less = require('gulp-less');
var watch = require('gulp-watch');
var path_less = '/css/less/';
var path_css = '/css/';
gulp.task('less2css', function () {
gulp.src(path_less + 'styles.less')
.pipe(less().on('error', gutil.log))
.pipe(gulp.dest(path_css))
});
gulp.task('watchless', function() {
gulp.watch(path_less + 'colors.less', ['less2css']); // Watch the colors.less file, then run the less2css task
});

How to remove ui-light.css from WinJS build?

WinJS or MobileFirst is injecting this piece of code on my index.html, the problem is ui-light.css is messing up with my .css even though it is the very first <link> on the <head>
Is there a way to remove this .css injection? I'd rather avoid doing javascript to remove a code that was just injected by javascript.
<script>
var head = document.getElementsByTagName('head')[0];
if (window.clientInformation.userAgent.indexOf("Windows Phone 8.1") > -1) {
var fileref1 = document.createElement("script");
var fileref2 = document.createElement("script");
var link = document.createElement('link');
fileref1.setAttribute("type", "text/javascript");
fileref1.setAttribute("src", "//Microsoft.Phone.WinJS.2.1/js/base.js");
fileref2.setAttribute("type", "text/javascript");
fileref2.setAttribute("src", "//Microsoft.Phone.WinJS.2.1/js/ui.js");
link.setAttribute("rel", "stylesheet");
link.setAttribute("href", "//Microsoft.Phone.WinJS.2.1/css/ui-light.css");
head.appendChild(fileref1);
head.appendChild(fileref2);
head.appendChild(link);
} else {
var fileref1 = document.createElement("script");
var fileref2 = document.createElement("script");
var link = document.createElement("link");
fileref1.setAttribute("type", "text/javascript");
fileref1.setAttribute("src", "//Microsoft.WinJS.2.0/js/base.js ");
fileref2.setAttribute("type", "text/javascript");
fileref2.setAttribute("src", "//Microsoft.WinJS.2.0/js/ui.js");
link.setAttribute("rel", "stylesheet");
link.setAttribute("href", "//Microsoft.WinJS.2.0/css/ui-light.css");
head.appendChild(fileref1);
head.appendChild(fileref2);
head.appendChild(link);
}
</script>
The latest version of winJS was 4.4. The ui-light/dark.css file was included in the WinJS library as a standalone css file. You can choose not to add it if it was messed up with your css. So, please try to update to winJS 4.4.

How do I create easily a PDF from an SVG with jsPDF?

I'm trying to create a pdf but I have some SVG pictures. I found information about this problem, but I just have to use JavaScript, that's to say, no jQuery.
I found jsPDF here : https://github.com/MrRio/jsPDF
There is the plugin jspdf.plugin.sillysvgrenderer.js (in the same folder) and where we can find an exemple of PDF created in the folder test.
But when I try to generate the PDF on my own, it doesn't work and I don't understand why.
Do you know how to do it?
I got this plugin working, but only with SVG file from the tests and the I saw in the doc that only PATHs are supported :(
There is already the issue on github
https://github.com/MrRio/jsPDF/issues/384
If paths are ok for here is my code (it's more or less the code from the tests):
function demoSvgDocument() {
var doc = new jsPDF();
var test = $.get('013_sillysvgrenderer.svg', function(svgText){
var svgAsText = new XMLSerializer().serializeToString(svgText.documentElement);
doc.addSVG(svgAsText, 20, 20, doc.internal.pageSize.width - 20*2)
// Save the PDF
doc.save('TestSVG.pdf');
});
}
Another point to consider, you have to run all examples on a server. Otherwise you won't see any results probably because of the security
Try canvg for that to covert SVG to Canvas. Then convert the canvas to base64 string using .toDataURL().
More detailed answer is here https://stackoverflow.com/a/35788928/2090459
Check the demo here http://jsfiddle.net/Purushoth/hvs91vpq/
Canvg Repo: https://github.com/gabelerner/canvg
There now is svg2pdf.js which uses a fork of jsPDF.
It has been created to solve this exact task: Exporting an SVG to a PDF.
Also in the meantime, jsPDF also added a demo that shows how to possibly export SVG using canvg and the jsPDF canvas implementation.
The two solutions have different advantages and disadvantages, so you might want to try both and see if one of them suits your needs.
You can use the canvas plugin that comes with jsPDF to render the SVG on the PDF with canvg. I've had to set a few dummy properties on the jsPDF canvas implementation, and disable the interactive/animation features of canvg for this to work without errors:
var jsPdfDoc = new jsPDF({
// ... options ...
});
// ... whatever ...
// hack to make the jspdf canvas work with canvg
jsPdfDoc.canvas.childNodes = {};
jsPdfDoc.context2d.canvas = jsPdfDoc.canvas;
jsPdfDoc.context2d.font = undefined;
// use the canvg render the SVG onto the
// PDF via the jsPDF canvas plugin.
canvg(jsPdfDoc.canvas, svgSource, {
ignoreMouse: true,
ignoreAnimation: true,
ignoreDimensions: true,
ignoreClear: true
});
This seems to me a much better solution than the SVG plugin for jsPDF, as canvg has much better support of SVG features. Note that the width and height properties should be set on the <svg/> element of your SVG for canvg to render it correctly (or at least so it seemed to me).
I modified this from: https://medium.com/#benjamin.black/using-blob-from-svg-text-as-image-source-2a8947af7a8e
var yourSVG = document.getElementsByTagName('svg')[0];
//or use document.getElementById('yourSvgId'); etc.
yourSVG.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', 'http://www.w3.org/2000/svg');
yourSVG.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', 'http://www.w3.org/1999/xlink');
var serializer = new XMLSerializer();
var serialSVG = serializer.serializeToString(yourSVG);
var svg = serialSVG;
var blob = new Blob([svg], {type: 'image/svg+xml'});
var url = URL.createObjectURL(blob);
var image = document.createElement('img');
// image.addEventListener('load', () => URL.revokeObjectURL(url), {once: true});
//changed above line using babel to code below;
image.addEventListener('load', function () {
return URL.revokeObjectURL(url);
}, { once: true });
image.src = url;
//Then just use your pdf.addImage() function as usual;

Get the loaded LESS file and compile it on demand

I'm trying to compile a small LESS portion of code and mixing it with a bigger one already compiled in the page.
I thought there was some way to reuse the compiled less or maybe load it again, mix it with the newer code and then compile it mixed in the page.
I thought to load it in some way like the example below:
var runtime_less = '#bg:red; .selector { background-color:#bg; }';
var library_less = '#var:bla bla bla...';
var library_parser = new(less.Parser)({
paths: ['.', './lib'], // Specify search paths for #import directives
filename: 'css/full_library.less' // Specify a filename, for better error messages
});
frontsize_parser.parse('', function (e, tree) {
library_less = tree;
});
var runtime_parser = new(less.Parser)({});
runtime_parser.parse(library_less, function (e, tree) {
// this should be inside some load event
$("#container-style").text(library_less.toCSS() + ' ' + tree.toCSS());
});
Does exist some way to get the current page loaded LESS file and treat it in some way?
Or does exist some way to load LESS files and then mix the LESS data with a string with additional LESS code?
with t.less containing:
#color: lightgreen;
You can use the following code:
<link type="text/css" href="t.less" rel="stylesheet/less">
<script>
less = {
env: "development"
};
</script>
<script src="/less.js/dist/less.js"></script>
<script>
var tmp = less.parse;
less.parse = function(input,option,callback) {
tmp(input + ' h1 {color:#color;}',option,callback);
}
less.refreshStyles();
</script>

usemin revved filenames and requirejs dependencies

I'm running into the following problem with requirejs and usemin:
I want to setup a multipage application, where I dynamically load modules that only contain page specific functionality (e.g. about -> about.js, home -> home.js). I could go ahead and pack everything in a single file, but that just leads to a bigger file size and overhead on functionality that isn't necessary on each site! (e.g. why would I need to load a carousel plugin on a page that doesn't have a carousel!)
I checked out the example https://github.com/requirejs/example-multipage-shim
That is in fact a great way to deal with it, until I bring usemin into the game. After revving the filenames the src path of each script tag is updated, but what about the dependencies?
<script src="scripts/vendor/1cdhj2.require.js"></script>
<script type="text/javascript">
require(['scripts/common'], function (common) {
require(['app'], function(App) {
App.initialize();
});
});
</script>
In that case, require.js got replaced by the revved file 1cdhj2.require.js. Great!
But the required modules "common" and "app" no longer work since common became 4jsh3b.common.js and app became 23jda3.app.js!
What can I do about this? Thanks for your help!
(Also using Yeoman, btw)
It's a tricky problem and I'm sure somebody else fixed in in a more elegant way, but the following works for me.
I might publish this as a grunt plugin once it's a little more robust.
Taken from my Gruntfile:
"regex-replace": {
rjsmodules: { // we'll build on this configuration later, inside the 'userevd-rjsmodules' task
src: ['build/**/*.js'],
actions: []
}
},
grunt.registerTask('userevd-rjsmodules', 'Make sure RequireJS modules are loaded by their revved module name', function() {
// scheduled search n replace actions
var actions = grunt.config("regex-replace").rjsmodules.actions;
// action object
var o = {
search: '',
replace: '', //<%= grunt.filerev.summary["build/js/app/detailsController.js"] %>
flags: 'g'
};
// read the requirejs config and look for optimized modules
var modules = grunt.config("requirejs.compile.options.modules");
var baseDir = grunt.config("requirejs.compile.options.dir");
var i, mod;
for (i in modules) {
mod = modules[i].name;
revvedMod = grunt.filerev.summary[baseDir + "/" + mod + ".js"];
revvedMod = revvedMod.replace('.js', '').replace(baseDir+'/','');
o.name = mod;
o.search = "'"+mod+"'";
// use the moduleid, and the grunt.filerev.summary object to find the revved file on disk
o.replace = "'"+revvedMod+"'";
// update the require(["xxx/yyy"]) declarations by scheduling a search/replace action
actions.push(o);
}
grunt.config.set('regex-replace.rjsmodules.actions', actions);
grunt.log.writeln('%j', grunt.config("regex-replace.rjsmodules"));
grunt.task.run("regex-replace:rjsmodules");
}),
You can also use requirejs' map config to specify a mapping between your original module and your revved one.
Filerev outputs a summary object containing a mapping of all the modules that were versioned and their original names. Use grunt file write feature to write a file in AMD way with the contents being the summary object:
// Default task(s).
grunt.registerTask('default', ['uglify', 'filerev', 'writeSummary']);
grunt.registerTask('writeSummary', 'Writes the summary output of filerev task to a file', function() {
grunt.file.write('filerevSummary.js', 'define([], function(){ return ' + JSON.stringify(grunt.filerev.summary) + '; })');
})
and use this file in your require config so that the new revved modules are used instead of old ones:
require(['../filerevSummary'], function(fileRev) {
var filerevMap = {};
for (var key in fileRev) {
var moduleID = key.split('/').pop().replace('.js', '');
var revvedModule = '../' + fileRev[key].replace('.js', '');
filerevMap[moduleID] = revvedModule;
}
require.config({
map: {
'*': filerevMap
}
});
The filerevMap object that I created above is specific to my folder structure. You can tweak it as per yours. It just loops through the filerev summary and makes sure the keys are modified as per your module names and values as per your folder structure.