2014-06-23 23:17:31 +02:00
|
|
|
'use strict';
|
|
|
|
|
|
2012-10-21 00:37:59 -06:00
|
|
|
var fs = require('fs');
|
|
|
|
|
var shell = require('shelljs');
|
|
|
|
|
var grunt = require('grunt');
|
2016-11-28 11:19:59 +00:00
|
|
|
var spawn = require('npm-run').spawn;
|
2014-03-11 06:34:09 +00:00
|
|
|
|
2013-10-14 12:06:26 -07:00
|
|
|
var CSP_CSS_HEADER = '/* Include this file in your html if you are using the CSP mode. */\n\n';
|
2012-10-21 00:37:59 -06:00
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
|
|
2021-02-05 21:00:44 +02:00
|
|
|
codeScriptFolder: 'scripts/code.angularjs.org-firebase',
|
2021-02-05 20:45:13 +02:00
|
|
|
|
2021-02-05 21:00:44 +02:00
|
|
|
docsScriptFolder: 'scripts/docs.angularjs.org-firebase',
|
2021-02-05 20:45:13 +02:00
|
|
|
|
2016-07-20 15:45:04 +02:00
|
|
|
startKarma: function(config, singleRun, done) {
|
2012-10-21 00:37:59 -06:00
|
|
|
var browsers = grunt.option('browsers');
|
|
|
|
|
var reporters = grunt.option('reporters');
|
|
|
|
|
var noColor = grunt.option('no-colors');
|
2013-07-01 16:21:56 -07:00
|
|
|
var port = grunt.option('port');
|
2016-11-28 11:19:59 +00:00
|
|
|
var p = spawn('karma', ['start', config,
|
2012-10-21 00:37:59 -06:00
|
|
|
singleRun ? '--single-run=true' : '',
|
|
|
|
|
reporters ? '--reporters=' + reporters : '',
|
|
|
|
|
browsers ? '--browsers=' + browsers : '',
|
2013-07-01 16:21:56 -07:00
|
|
|
noColor ? '--no-colors' : '',
|
|
|
|
|
port ? '--port=' + port : ''
|
2012-10-21 00:37:59 -06:00
|
|
|
]);
|
|
|
|
|
p.stdout.pipe(process.stdout);
|
|
|
|
|
p.stderr.pipe(process.stderr);
|
2016-07-20 15:45:04 +02:00
|
|
|
p.on('exit', function(code) {
|
2016-08-10 12:13:14 +02:00
|
|
|
if (code !== 0) grunt.fail.warn('Karma test(s) failed. Exit code: ' + code);
|
2012-10-21 00:37:59 -06:00
|
|
|
done();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2016-07-20 15:45:04 +02:00
|
|
|
updateWebdriver: function(done) {
|
2020-05-21 09:13:46 +01:00
|
|
|
if (process.env.CI) {
|
|
|
|
|
// Skip the webdriver-manager update on CI, since the browsers will
|
2014-01-28 13:56:33 -08:00
|
|
|
// be provided remotely.
|
|
|
|
|
done();
|
2014-01-30 18:49:58 -08:00
|
|
|
return;
|
2014-01-28 13:56:33 -08:00
|
|
|
}
|
2016-11-28 11:19:59 +00:00
|
|
|
var p = spawn('webdriver-manager', ['update']);
|
2014-01-07 11:51:32 -08:00
|
|
|
p.stdout.pipe(process.stdout);
|
|
|
|
|
p.stderr.pipe(process.stderr);
|
2016-07-20 15:45:04 +02:00
|
|
|
p.on('exit', function(code) {
|
|
|
|
|
if (code !== 0) grunt.fail.warn('Webdriver failed to update');
|
2014-01-07 11:51:32 -08:00
|
|
|
done();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2016-07-20 15:45:04 +02:00
|
|
|
startProtractor: function(config, done) {
|
2014-01-07 11:51:32 -08:00
|
|
|
var sauceUser = grunt.option('sauceUser');
|
|
|
|
|
var sauceKey = grunt.option('sauceKey');
|
|
|
|
|
var tunnelIdentifier = grunt.option('capabilities.tunnel-identifier');
|
|
|
|
|
var sauceBuild = grunt.option('capabilities.build');
|
2014-01-30 18:49:58 -08:00
|
|
|
var browser = grunt.option('browser');
|
2014-02-19 21:01:54 -08:00
|
|
|
var specs = grunt.option('specs');
|
2016-09-01 20:42:03 +02:00
|
|
|
var args = [config];
|
2014-01-07 11:51:32 -08:00
|
|
|
if (sauceUser) args.push('--sauceUser=' + sauceUser);
|
|
|
|
|
if (sauceKey) args.push('--sauceKey=' + sauceKey);
|
|
|
|
|
if (tunnelIdentifier) args.push('--capabilities.tunnel-identifier=' + tunnelIdentifier);
|
|
|
|
|
if (sauceBuild) args.push('--capabilities.build=' + sauceBuild);
|
2014-02-19 21:01:54 -08:00
|
|
|
if (specs) args.push('--specs=' + specs);
|
2014-01-30 18:49:58 -08:00
|
|
|
if (browser) {
|
|
|
|
|
args.push('--browser=' + browser);
|
|
|
|
|
}
|
2014-01-07 11:51:32 -08:00
|
|
|
|
|
|
|
|
|
2016-11-28 11:19:59 +00:00
|
|
|
var p = spawn('protractor', args);
|
2014-01-07 11:51:32 -08:00
|
|
|
p.stdout.pipe(process.stdout);
|
|
|
|
|
p.stderr.pipe(process.stderr);
|
2016-07-20 15:45:04 +02:00
|
|
|
p.on('exit', function(code) {
|
|
|
|
|
if (code !== 0) grunt.fail.warn('Protractor test(s) failed. Exit code: ' + code);
|
2014-01-07 11:51:32 -08:00
|
|
|
done();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2018-12-10 14:38:57 +00:00
|
|
|
wrap(src, name) {
|
|
|
|
|
return [`src/${name}.prefix`, ...src, `src/${name}.suffix`];
|
2012-10-21 00:37:59 -06:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2016-07-20 15:45:04 +02:00
|
|
|
addStyle: function(src, styles, minify) {
|
2013-10-14 12:06:26 -07:00
|
|
|
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);
|
2012-10-21 00:37:59 -06:00
|
|
|
|
2016-07-20 15:45:04 +02:00
|
|
|
if (minify) {
|
2012-10-21 00:37:59 -06:00
|
|
|
css = css
|
2013-04-16 12:13:55 +01:00
|
|
|
.replace(/\r?\n/g, '')
|
2012-10-21 00:37:59 -06:00
|
|
|
.replace(/\/\*.*?\*\//g, '')
|
|
|
|
|
.replace(/:\s+/g, ':')
|
|
|
|
|
.replace(/\s*\{\s*/g, '{')
|
|
|
|
|
.replace(/\s*\}\s*/g, '}')
|
2016-07-20 15:45:04 +02:00
|
|
|
.replace(/\s*,\s*/g, ',')
|
|
|
|
|
.replace(/\s*;\s*/g, ';');
|
2012-10-21 00:37:59 -06:00
|
|
|
}
|
2013-04-16 12:13:55 +01:00
|
|
|
//escape for js
|
2012-10-21 00:37:59 -06:00
|
|
|
css = css
|
|
|
|
|
.replace(/\\/g, '\\\\')
|
2016-08-10 12:13:14 +02:00
|
|
|
.replace(/'/g, '\\\'')
|
2013-04-16 12:13:55 +01:00
|
|
|
.replace(/\r?\n/g, '\\n');
|
2020-05-24 20:09:21 +03:00
|
|
|
js = '!window.angular.$$csp().noInlineStyle && window.angular.element(document.head).prepend(window.angular.element(\'<style>\').text(\'' + css + '\'));';
|
2013-10-14 12:06:26 -07:00
|
|
|
state.js.push(js);
|
|
|
|
|
|
|
|
|
|
return state;
|
2012-10-21 00:37:59 -06:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2016-07-20 15:45:04 +02:00
|
|
|
process: function(src, NG_VERSION, strict) {
|
2012-10-21 00:37:59 -06:00
|
|
|
var processed = src
|
2016-08-12 02:25:48 +03:00
|
|
|
.replace(/(['"])NG_VERSION_FULL\1/g, NG_VERSION.full)
|
|
|
|
|
.replace(/(['"])NG_VERSION_MAJOR\1/, NG_VERSION.major)
|
|
|
|
|
.replace(/(['"])NG_VERSION_MINOR\1/, NG_VERSION.minor)
|
|
|
|
|
.replace(/(['"])NG_VERSION_DOT\1/, NG_VERSION.patch)
|
|
|
|
|
.replace(/(['"])NG_VERSION_CDN\1/, NG_VERSION.cdn)
|
|
|
|
|
.replace(/(['"])NG_VERSION_CODENAME\1/, NG_VERSION.codeName);
|
2012-10-21 00:37:59 -06:00
|
|
|
if (strict !== false) processed = this.singleStrict(processed, '\n\n', true);
|
|
|
|
|
return processed;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2016-07-20 15:45:04 +02:00
|
|
|
build: function(config, fn) {
|
2012-10-21 00:37:59 -06:00
|
|
|
var files = grunt.file.expand(config.src);
|
2018-12-10 16:33:01 +00:00
|
|
|
// grunt.file.expand might reorder the list of files
|
|
|
|
|
// when it is expanding globs, so we use prefix and suffix
|
|
|
|
|
// fields to ensure that files are at the start of end of
|
|
|
|
|
// the list (primarily for wrapping in an IIFE).
|
|
|
|
|
if (config.prefix) {
|
|
|
|
|
files = grunt.file.expand(config.prefix).concat(files);
|
|
|
|
|
}
|
|
|
|
|
if (config.suffix) {
|
|
|
|
|
files = files.concat(grunt.file.expand(config.suffix));
|
|
|
|
|
}
|
2012-10-21 00:37:59 -06:00
|
|
|
var styles = config.styles;
|
2013-10-14 12:06:26 -07:00
|
|
|
var processedStyles;
|
2012-10-21 00:37:59 -06:00
|
|
|
//concat
|
2013-10-14 12:06:26 -07:00
|
|
|
var src = files.map(function(filepath) {
|
2012-10-21 00:37:59 -06:00
|
|
|
return grunt.file.read(filepath);
|
|
|
|
|
}).join(grunt.util.normalizelf('\n'));
|
|
|
|
|
//process
|
|
|
|
|
var processed = this.process(src, grunt.config('NG_VERSION'), config.strict);
|
2013-10-14 12:06:26 -07:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-10-21 00:37:59 -06:00
|
|
|
//write
|
|
|
|
|
grunt.file.write(config.dest, processed);
|
|
|
|
|
grunt.log.ok('File ' + config.dest + ' created.');
|
|
|
|
|
fn();
|
2013-10-14 12:06:26 -07:00
|
|
|
|
|
|
|
|
function removeSuffix(fileName) {
|
|
|
|
|
return fileName.replace(/\.js$/, '');
|
|
|
|
|
}
|
2012-10-21 00:37:59 -06:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2016-07-20 15:45:04 +02:00
|
|
|
singleStrict: function(src, insert) {
|
2012-10-21 00:37:59 -06:00
|
|
|
return src
|
|
|
|
|
.replace(/\s*("|')use strict("|');\s*/g, insert) // remove all file-specific strict mode flags
|
2016-08-10 12:13:14 +02:00
|
|
|
.replace(/(\(function\([^)]*\)\s*\{)/, '$1\'use strict\';'); // add single strict mode flag
|
2013-06-07 10:25:07 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sourceMap: function(mapFile, fileContents) {
|
2013-09-24 19:52:20 +02:00
|
|
|
var sourceMapLine = '//# sourceMappingURL=' + mapFile + '\n';
|
2013-06-07 10:25:07 -07:00
|
|
|
return fileContents + sourceMapLine;
|
2012-10-21 00:37:59 -06:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
min: function(file, done) {
|
2016-08-10 12:13:14 +02:00
|
|
|
var classPathSep = (process.platform === 'win32') ? ';' : ':';
|
2012-10-21 00:37:59 -06:00
|
|
|
var minFile = file.replace(/\.js$/, '.min.js');
|
2013-06-07 10:25:07 -07:00
|
|
|
var mapFile = minFile + '.map';
|
2016-11-25 14:54:49 +00:00
|
|
|
var mapFileName = mapFile.match(/[^/]+$/)[0];
|
2013-06-28 16:47:10 -07:00
|
|
|
var errorFileName = file.replace(/\.js$/, '-errors.json');
|
2014-03-11 06:34:09 +00:00
|
|
|
var versionNumber = grunt.config('NG_VERSION').full;
|
2015-04-14 18:10:13 -07:00
|
|
|
var compilationLevel = (file === 'build/angular-message-format.js') ?
|
feat($interpolate): extend interpolation with MessageFormat like syntax
For more detailed information refer to this document:
https://docs.google.com/a/google.com/document/d/1pbtW2yvtmFBikfRrJd8VAsabiFkKezmYZ_PbgdjQOVU/edit
**Example:**
```html
{{recipients.length, plural, offset:1
=0 {You gave no gifts}
=1 { {{ recipients[0].gender, select,
male {You gave him a gift.}
female {You gave her a gift.}
other {You gave them a gift.}
}}
}
one { {{ recipients[0].gender, select,
male {You gave him and one other person a gift.}
female {You gave her and one other person a gift.}
other {You gave them and one other person a gift.}
}}
}
other {You gave {{recipients[0].gender}} and # other people gifts. }
}}
```
This is a SEPARATE module so you MUST include `angular-messageformat.js`
or `angular-messageformat.min.js`.
In addition, your application module should depend on the "ngMessageFormat"
(e.g. angular.module('myApp', ['ngMessageFormat']);)
When you use the `ngMessageFormat`, the $interpolate gets overridden with
a new service that adds the new MessageFormat behavior.
**Syntax differences from MessageFormat:**
- MessageFormat directives are always inside `{{ }}` instead of
single `{ }`. This ensures a consistent interpolation syntax (else you
could interpolate in more than one way and have to pick one based on
the features availability for that syntax.)
- The first part of such a syntax can be an arbitrary Angular
expression instead of a single identifier.
- You can nest them as deep as you want. As mentioned earlier, you
would use `{{ }}` to start the nested interpolation that may optionally
include select/plural extensions.
- Only `select` and `plural` keywords are currently recognized.
- Quoting support is coming in a future commit.
- Positional arguments/placeholders are not supported. They don't make
sense in Angular templates anyway (they are only helpful when using
API calls from a programming language.)
- Redefining of the startSymbol (`{{`) and endSymbol (`}}`) used for
interpolation is not yet supported.
Closes #11152
2015-02-12 13:45:25 -08:00
|
|
|
'ADVANCED_OPTIMIZATIONS' : 'SIMPLE_OPTIMIZATIONS';
|
2012-10-21 00:37:59 -06:00
|
|
|
shell.exec(
|
|
|
|
|
'java ' +
|
|
|
|
|
this.java32flags() + ' ' +
|
2015-04-29 14:43:05 +01:00
|
|
|
this.memoryRequirement() + ' ' +
|
2017-12-27 19:16:46 +01:00
|
|
|
'-cp vendor/closure-compiler/compiler.jar' + classPathSep +
|
|
|
|
|
'vendor/ng-closure-runner/ngcompiler.jar ' +
|
2013-06-28 16:47:10 -07:00
|
|
|
'org.angularjs.closurerunner.NgClosureRunner ' +
|
feat($interpolate): extend interpolation with MessageFormat like syntax
For more detailed information refer to this document:
https://docs.google.com/a/google.com/document/d/1pbtW2yvtmFBikfRrJd8VAsabiFkKezmYZ_PbgdjQOVU/edit
**Example:**
```html
{{recipients.length, plural, offset:1
=0 {You gave no gifts}
=1 { {{ recipients[0].gender, select,
male {You gave him a gift.}
female {You gave her a gift.}
other {You gave them a gift.}
}}
}
one { {{ recipients[0].gender, select,
male {You gave him and one other person a gift.}
female {You gave her and one other person a gift.}
other {You gave them and one other person a gift.}
}}
}
other {You gave {{recipients[0].gender}} and # other people gifts. }
}}
```
This is a SEPARATE module so you MUST include `angular-messageformat.js`
or `angular-messageformat.min.js`.
In addition, your application module should depend on the "ngMessageFormat"
(e.g. angular.module('myApp', ['ngMessageFormat']);)
When you use the `ngMessageFormat`, the $interpolate gets overridden with
a new service that adds the new MessageFormat behavior.
**Syntax differences from MessageFormat:**
- MessageFormat directives are always inside `{{ }}` instead of
single `{ }`. This ensures a consistent interpolation syntax (else you
could interpolate in more than one way and have to pick one based on
the features availability for that syntax.)
- The first part of such a syntax can be an arbitrary Angular
expression instead of a single identifier.
- You can nest them as deep as you want. As mentioned earlier, you
would use `{{ }}` to start the nested interpolation that may optionally
include select/plural extensions.
- Only `select` and `plural` keywords are currently recognized.
- Quoting support is coming in a future commit.
- Positional arguments/placeholders are not supported. They don't make
sense in Angular templates anyway (they are only helpful when using
API calls from a programming language.)
- Redefining of the startSymbol (`{{`) and endSymbol (`}}`) used for
interpolation is not yet supported.
Closes #11152
2015-02-12 13:45:25 -08:00
|
|
|
'--compilation_level ' + compilationLevel + ' ' +
|
2012-10-21 00:37:59 -06:00
|
|
|
'--language_in ECMASCRIPT5_STRICT ' +
|
2013-06-28 16:47:10 -07:00
|
|
|
'--minerr_pass ' +
|
|
|
|
|
'--minerr_errors ' + errorFileName + ' ' +
|
2013-07-25 14:35:53 -07:00
|
|
|
'--minerr_url http://errors.angularjs.org/' + versionNumber + '/ ' +
|
2013-06-07 10:25:07 -07:00
|
|
|
'--source_map_format=V3 ' +
|
|
|
|
|
'--create_source_map ' + mapFile + ' ' +
|
2012-10-21 00:37:59 -06:00
|
|
|
'--js ' + file + ' ' +
|
|
|
|
|
'--js_output_file ' + minFile,
|
|
|
|
|
function(code) {
|
|
|
|
|
if (code !== 0) grunt.fail.warn('Error minifying ' + file);
|
2013-06-07 10:25:07 -07:00
|
|
|
|
|
|
|
|
// closure creates the source map relative to build/ folder, we need to strip those references
|
|
|
|
|
grunt.file.write(mapFile, grunt.file.read(mapFile).replace('"file":"build/', '"file":"').
|
|
|
|
|
replace('"sources":["build/','"sources":["'));
|
|
|
|
|
|
|
|
|
|
// move add use strict into the closure + add source map pragma
|
|
|
|
|
grunt.file.write(minFile, this.sourceMap(mapFileName, this.singleStrict(grunt.file.read(minFile), '\n')));
|
2012-10-21 00:37:59 -06:00
|
|
|
grunt.log.ok(file + ' minified into ' + minFile);
|
|
|
|
|
done();
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
2015-04-29 14:43:05 +01:00
|
|
|
memoryRequirement: function() {
|
|
|
|
|
return (process.platform === 'win32') ? '' : '-Xmx2g';
|
|
|
|
|
},
|
|
|
|
|
|
2012-10-21 00:37:59 -06:00
|
|
|
|
|
|
|
|
//returns the 32-bit mode force flags for java compiler if supported, this makes the build much faster
|
2016-07-20 15:45:04 +02:00
|
|
|
java32flags: function() {
|
2016-08-10 12:13:14 +02:00
|
|
|
if (process.platform === 'win32') return '';
|
2018-06-20 13:19:03 -04:00
|
|
|
if (shell.exec('java -d32 -version 2>&1', {silent: true}).code !== 0) return '';
|
2012-10-21 00:37:59 -06:00
|
|
|
return ' -d32 -client';
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2013-06-28 16:47:10 -07:00
|
|
|
//collects and combines error messages stripped out in minify step
|
2016-07-20 15:45:04 +02:00
|
|
|
collectErrors: function() {
|
2013-06-28 16:47:10 -07:00
|
|
|
var combined = {
|
|
|
|
|
id: 'ng',
|
|
|
|
|
generated: new Date().toString(),
|
|
|
|
|
errors: {}
|
|
|
|
|
};
|
2016-07-20 15:45:04 +02:00
|
|
|
grunt.file.expand('build/*-errors.json').forEach(function(file) {
|
2013-06-28 16:47:10 -07:00
|
|
|
var errors = grunt.file.readJSON(file),
|
|
|
|
|
namespace;
|
2016-07-20 15:45:04 +02:00
|
|
|
Object.keys(errors).forEach(function(prop) {
|
2013-06-28 16:47:10 -07:00
|
|
|
if (typeof errors[prop] === 'object') {
|
|
|
|
|
namespace = errors[prop];
|
|
|
|
|
if (combined.errors[prop]) {
|
2016-07-20 15:45:04 +02:00
|
|
|
Object.keys(namespace).forEach(function(code) {
|
2013-06-28 16:47:10 -07:00
|
|
|
if (combined.errors[prop][code] && combined.errors[prop][code] !== namespace[code]) {
|
|
|
|
|
grunt.warn('[collect-errors] Duplicate minErr codes don\'t match!');
|
|
|
|
|
} else {
|
|
|
|
|
combined.errors[prop][code] = namespace[code];
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
combined.errors[prop] = namespace;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (combined.errors[prop] && combined.errors[prop] !== errors[prop]) {
|
|
|
|
|
grunt.warn('[collect-errors] Duplicate minErr codes don\'t match!');
|
|
|
|
|
} else {
|
|
|
|
|
combined.errors[prop] = errors[prop];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
grunt.file.write('build/errors.json', JSON.stringify(combined));
|
|
|
|
|
grunt.file.expand('build/*-errors.json').forEach(grunt.file.delete);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2012-10-21 00:37:59 -06:00
|
|
|
//csp connect middleware
|
2016-07-20 15:45:04 +02:00
|
|
|
conditionalCsp: function() {
|
|
|
|
|
return function(req, res, next) {
|
2014-09-17 10:43:49 -07:00
|
|
|
var CSP = /\.csp\W/;
|
|
|
|
|
|
|
|
|
|
if (CSP.test(req.url)) {
|
2016-08-10 12:13:14 +02:00
|
|
|
res.setHeader('X-WebKit-CSP', 'default-src \'self\';');
|
|
|
|
|
res.setHeader('X-Content-Security-Policy', 'default-src \'self\'');
|
|
|
|
|
res.setHeader('Content-Security-Policy', 'default-src \'self\'');
|
2014-09-17 10:43:49 -07:00
|
|
|
}
|
2012-10-21 00:37:59 -06:00
|
|
|
next();
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//rewrite connect middleware
|
2016-07-20 15:45:04 +02:00
|
|
|
rewrite: function() {
|
|
|
|
|
return function(req, res, next) {
|
2013-07-12 17:42:27 -07:00
|
|
|
var REWRITE = /\/(guide|api|cookbook|misc|tutorial|error).*$/,
|
2016-02-22 13:55:48 +00:00
|
|
|
IGNORED = /(\.(css|js|png|jpg|gif|svg)$|partials\/.*\.html$)/,
|
2012-10-21 00:37:59 -06:00
|
|
|
match;
|
|
|
|
|
|
|
|
|
|
if (!IGNORED.test(req.url) && (match = req.url.match(REWRITE))) {
|
|
|
|
|
console.log('rewriting', req.url);
|
|
|
|
|
req.url = req.url.replace(match[0], '/index.html');
|
|
|
|
|
}
|
|
|
|
|
next();
|
|
|
|
|
};
|
2014-12-04 14:19:09 -08:00
|
|
|
}
|
2021-02-05 20:45:13 +02:00
|
|
|
|
2012-10-21 00:37:59 -06:00
|
|
|
};
|