diff options
| -rw-r--r-- | Gruntfile.js | 1 | ||||
| -rw-r--r-- | lib/grunt/utils.js | 41 | ||||
| -rw-r--r-- | src/ng/directive/ngCloak.js | 3 | ||||
| -rw-r--r-- | src/ng/directive/ngCsp.js | 4 | ||||
| -rw-r--r-- | src/ng/directive/ngShowHide.js | 2 | 
5 files changed, 41 insertions, 10 deletions
| diff --git a/Gruntfile.js b/Gruntfile.js index c4d2bb21..8c957e63 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -121,6 +121,7 @@ module.exports = function(grunt) {          src: util.wrap([files['angularSrc']], 'angular'),          styles: {            css: ['css/angular.css'], +          generateCspCssFile: true,            minify: true          }        }, diff --git a/lib/grunt/utils.js b/lib/grunt/utils.js index c7d4431b..ababf2f6 100644 --- a/lib/grunt/utils.js +++ b/lib/grunt/utils.js @@ -3,6 +3,7 @@ var shell = require('shelljs');  var grunt = require('grunt');  var spawn = require('child_process').spawn;  var version; +var CSP_CSS_HEADER = '/* Include this file in your html if you are using the CSP mode. */\n\n';  module.exports = { @@ -70,12 +71,20 @@ module.exports = {    addStyle: function(src, styles, minify){ -    styles = styles.map(processCSS.bind(this)).join('\n'); -    src += styles; -    return src; +    styles = styles.reduce(processCSS.bind(this), { +      js: [src], +      css: [] +    }); +    return { +      js: styles.js.join('\n'), +      css: styles.css.join('\n') +    }; + +    function processCSS(state, file) { +      var css = fs.readFileSync(file).toString(), +        js; +      state.css.push(css); -    function processCSS(file){ -      var css = fs.readFileSync(file).toString();        if(minify){          css = css            .replace(/\r?\n/g, '') @@ -91,7 +100,10 @@ module.exports = {          .replace(/\\/g, '\\\\')          .replace(/'/g, "\\'")          .replace(/\r?\n/g, '\\n'); -      return "!angular.$$csp() && angular.element(document).find('head').prepend('<style type=\"text/css\">" + css + "</style>');"; +      js = "!angular.$$csp() && angular.element(document).find('head').prepend('<style type=\"text/css\">" + css + "</style>');"; +      state.js.push(js); + +      return state;      }    }, @@ -100,7 +112,7 @@ module.exports = {      var processed = src        .replace(/"NG_VERSION_FULL"/g, NG_VERSION.full)        .replace(/"NG_VERSION_MAJOR"/, NG_VERSION.major) -      .replace(/"NG_VERSION_MINOR"/, NG_VERSION.minor) +      .replace(/"NG_VERSION_ MINOR"/, NG_VERSION.minor)        .replace(/"NG_VERSION_DOT"/, NG_VERSION.dot)        .replace(/"NG_VERSION_CDN"/, NG_VERSION.cdn)        .replace(/"NG_VERSION_CODENAME"/, NG_VERSION.codename); @@ -112,17 +124,28 @@ module.exports = {    build: function(config, fn){      var files = grunt.file.expand(config.src);      var styles = config.styles; +    var processedStyles;      //concat -    var src = files.map(function(filepath){ +    var src = files.map(function(filepath) {        return grunt.file.read(filepath);      }).join(grunt.util.normalizelf('\n'));      //process      var processed = this.process(src, grunt.config('NG_VERSION'), config.strict); -    if (styles) processed = this.addStyle(processed, styles.css, styles.minify); +    if (styles) { +      processedStyles = this.addStyle(processed, styles.css, styles.minify); +      processed = processedStyles.js; +      if (config.styles.generateCspCssFile) { +        grunt.file.write(removeSuffix(config.dest) + '-csp.css', CSP_CSS_HEADER + processedStyles.css); +      } +    }      //write      grunt.file.write(config.dest, processed);      grunt.log.ok('File ' + config.dest + ' created.');      fn(); + +    function removeSuffix(fileName) { +      return fileName.replace(/\.js$/, ''); +    }    }, diff --git a/src/ng/directive/ngCloak.js b/src/ng/directive/ngCloak.js index 6e39bdfc..d430ae52 100644 --- a/src/ng/directive/ngCloak.js +++ b/src/ng/directive/ngCloak.js @@ -15,7 +15,8 @@   * of the browser view.   *   * `ngCloak` works in cooperation with the following css rule embedded within `angular.js` and - *  `angular.min.js`: + * `angular.min.js`. + * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}).   *   * <pre>   * [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { diff --git a/src/ng/directive/ngCsp.js b/src/ng/directive/ngCsp.js index f1a71d4c..fc90d46a 100644 --- a/src/ng/directive/ngCsp.js +++ b/src/ng/directive/ngCsp.js @@ -19,6 +19,10 @@   * evaluate all expressions up to 30% slower than in non-CSP mode, but no security violations will   * be raised.   * + * CSP forbids JavaScript to inline stylesheet rules. In non CSP mode Angular automatically + * includes some CSS rules (e.g. {@link ng.directive:ngCloak ngCloak}). + * To make those directives work in CSP mode, include the `angular-csp.css` manually. + *   * In order to use this feature put the `ngCsp` directive on the root element of the application.   *   * *Note: This directive is only available in the `ng-csp` and `data-ng-csp` attribute form.* diff --git a/src/ng/directive/ngShowHide.js b/src/ng/directive/ngShowHide.js index cdfa0604..5b13a57b 100644 --- a/src/ng/directive/ngShowHide.js +++ b/src/ng/directive/ngShowHide.js @@ -9,6 +9,7 @@   * provided to the ngShow attribute. The element is shown or hidden by removing or adding   * the `ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined   * in AngularJS and sets the display style to none (using an !important flag). + * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}).   *   * <pre>   * <!-- when $scope.myValue is truthy (element is visible) --> @@ -161,6 +162,7 @@ var ngShowDirective = ['$animate', function($animate) {   * provided to the ngHide attribute. The element is shown or hidden by removing or adding   * the `ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined   * in AngularJS and sets the display style to none (using an !important flag). + * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}).   *   * <pre>   * <!-- when $scope.myValue is truthy (element is hidden) --> | 
