diff --git a/.gitignore b/.gitignore
index faf8ca8d9..414f2d8fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ Thumbs.db
.DS_Store
/deploy
build/node_modules
+build/plugins/**/node_modules/
build/sprites/node_modules/
vendor/framework7-react/
apps/documenteditor/embed/resources/less/node_modules
diff --git a/build/Gruntfile.js b/build/Gruntfile.js
index f9feb9b9b..509e36b36 100644
--- a/build/Gruntfile.js
+++ b/build/Gruntfile.js
@@ -106,7 +106,7 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-json-minify');
grunt.loadNpmTasks('grunt-text-replace');
// grunt.loadNpmTasks('grunt-mocha');
- // grunt.loadNpmTasks('grunt-inline');
+ grunt.loadNpmTasks('grunt-inline');
grunt.loadNpmTasks('grunt-svgmin');
grunt.loadNpmTasks('grunt-exec');
@@ -396,9 +396,9 @@ module.exports = function(grunt) {
localization: {
files: packageFile['main']['copy']['localization']
},
- help: {
- files: packageFile['main']['copy']['help']
- },
+ // help: {
+ // files: packageFile['main']['copy']['help']
+ // },
indexhtml: {
files: packageFile['main']['copy']['indexhtml']
}
@@ -660,7 +660,7 @@ module.exports = function(grunt) {
grunt.registerTask('deploy-common-embed', ['common-embed-init', 'clean', 'copy']);
grunt.registerTask('deploy-app-main', ['prebuild-icons-sprite', 'main-app-init', 'clean:prebuild', 'imagemin', 'less',
- 'requirejs', 'concat', 'copy', 'svgmin', /*'inline',*/ 'json-minify',
+ 'requirejs', 'concat', 'copy', 'svgmin', 'inline', 'json-minify',
'replace:writeVersion', 'replace:prepareHelp', 'clean:postbuild']);
grunt.registerTask('deploy-app-mobile', ['mobile-app-init', 'clean:deploy', /*'cssmin',*/ /*'copy:template-backup',*/
diff --git a/build/package.json b/build/package.json
index eb3bf793c..0d9c0dbc2 100644
--- a/build/package.json
+++ b/build/package.json
@@ -4,7 +4,7 @@
"homepage": "http://www.onlyoffice.com",
"private": true,
"dependencies": {
- "grunt": "^1.0.0",
+ "grunt": "^1.4.1",
"grunt-contrib-clean": "^2.0.0",
"grunt-contrib-concat": "^2.0.0",
"grunt-contrib-copy": "^1.0.0",
@@ -15,6 +15,7 @@
"grunt-contrib-requirejs": "^1.0.0",
"grunt-contrib-uglify": "^5.0.1",
"grunt-exec": "^3.0.0",
+ "grunt-inline": "file:plugins/grunt-inline",
"grunt-json-minify": "^1.1.0",
"grunt-spritesmith": "^6.9.0",
"grunt-svgmin": "^6.0.1",
diff --git a/build/plugins/grunt-inline/Gruntfile.js b/build/plugins/grunt-inline/Gruntfile.js
new file mode 100644
index 000000000..59e6e3271
--- /dev/null
+++ b/build/plugins/grunt-inline/Gruntfile.js
@@ -0,0 +1,50 @@
+'use strict';
+
+module.exports = function(grunt) {
+ grunt.initConfig({
+ inline: {
+ dist: {
+ src: ['test/dist/*.html'],
+ dest: ['tmp/']
+ }
+ },
+
+ clean: {
+ tests: ['tmp/']
+ },
+
+ htmlmin: {
+ dist: {
+ options: {
+ removeComments: true,
+ collapseWhitespace: true
+ },
+ files: {
+ 'tmp/css.min.html': 'tmp/css.html',
+ 'tmp/img.min.html': 'tmp/img.html',
+ 'tmp/html.min.html': 'tmp/html.html',
+ 'tmp/script.min.html': 'tmp/script.html',
+ 'tmp/css_greedy.min.html': 'tmp/css_greedy.html',
+ 'tmp/img_greedy.min.html': 'tmp/img_greedy.html',
+ 'tmp/html_greedy.min.html': 'tmp/html_greedy.html',
+ 'tmp/script_greedy.min.html': 'tmp/script_greedy.html'
+ }
+ }
+ },
+
+ // Unit tests
+ nodeunit: {
+ tests: ['test/*_test.js']
+ }
+ });
+
+ grunt.loadTasks('tasks');
+
+ grunt.loadNpmTasks('grunt-contrib-clean');
+ grunt.loadNpmTasks('grunt-contrib-htmlmin');
+ grunt.loadNpmTasks('grunt-contrib-nodeunit');
+
+ grunt.registerTask('test', ['clean', 'inline', 'htmlmin', 'nodeunit']);
+ // By default, run all tests
+ grunt.registerTask('default', ['test']);
+};
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/LICENSE-MIT b/build/plugins/grunt-inline/LICENSE-MIT
new file mode 100644
index 000000000..e19969fa6
--- /dev/null
+++ b/build/plugins/grunt-inline/LICENSE-MIT
@@ -0,0 +1,22 @@
+Copyright (c) 2014 陈映平, contributors
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/build/plugins/grunt-inline/README.md b/build/plugins/grunt-inline/README.md
new file mode 100644
index 000000000..fbfd13d07
--- /dev/null
+++ b/build/plugins/grunt-inline/README.md
@@ -0,0 +1,274 @@
+# grunt-inline[![build status](https://secure.travis-ci.org/miniflycn/grunt-inline.png)](http://travis-ci.org/miniflycn/grunt-inline)
+
+Brings externally referenced resources, such as js, css and images, into
+a single file.
+
+For exmample:
+
+```html
+
+```
+
+is replaced with
+
+```html
+
+```
+
+JavaScript references are brought inline, and images in the html
+and css blocks are converted to base-64 data: urls.
+
+By default, only urls marked with `__inline` are converted, however this
+behavior can be overrided via the `tag:` option.
+
+
+## Getting Started
+
+This plugin requires Grunt `~0.4.1`
+
+If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
+
+```bash
+npm install grunt-inline --save-dev
+```
+
+Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
+
+```bash
+grunt.loadNpmTasks('grunt-inline');
+```
+
+## The "grunt-inline" task
+
+### Overview
+
+In your project's Gruntfile, add a section named `inline` to the data object passed into `grunt.initConfig()`.
+
+```javascript
+grunt.initConfig({
+ inline: {
+ dist: {
+ src: 'src/index.html',
+ dest: 'dist/index.html'
+ }
+ }
+});
+```
+
+### Options
+
+#### dest
+
+If dest is assigned, the the source file will be copied to the destination path. eg:
+`src/index.html` will be processed and then copied to `dist/index.html`
+
+```javascript
+grunt.initConfig({
+ inline: {
+ dist: {
+ src: 'src/index.html',
+ dest: 'dist/index.html'
+ }
+ }
+});
+```
+
+### cssmin
+
+If cssmin is assigned true, `.css` will be minified before inlined.
+
+```javascript
+grunt.initConfig({
+ inline: {
+ dist: {
+ options:{
+ cssmin: true
+ },
+ src: 'src/index.html',
+ dest: 'dist/index.html'
+ }
+ }
+});
+```
+
+### tag (defaults to ```__inline```)
+
+Only URLs that contain the value for ```tag``` will be inlined.
+Specify ```tag: ''``` to include all urls.
+
+```javascript
+grunt.initConfig({
+ inline: {
+ dist: {
+ options:{
+ tag: ''
+ },
+ src: 'src/index.html',
+ dest: 'dist/index.html']
+ }
+ }
+});
+```
+
+
+### inlineTagAttributes
+
+Ability to add attributes string to inline tag.
+
+```javascript
+grunt.initConfig({
+ inline: {
+ dist: {
+ options:{
+ inlineTagAttributes: {
+ js: 'data-inlined="true"', // Adds
+ css: 'data-inlined="true"' // Adds
+ },
+ src: 'src/index.html',
+ dest: 'dist/index.html'
+ }
+ }
+ }
+});
+```
+
+### uglify
+
+If uglify is assigned true, `.js` file will be minified before inlined.
+
+```javascript
+grunt.initConfig({
+ inline: {
+ dist: {
+ options:{
+ uglify: true
+ },
+ src: 'src/index.html',
+ dest: 'dist/index.html'
+ }
+ }
+});
+```
+
+### exts
+
+Setting an exts array allows multiple file extensions to be processed as
+html.
+
+```javascript
+grunt.initConfig({
+ inline: {
+ dist: {
+ options:{
+ exts: ['jade'],
+ uglify: true
+ },
+ src: 'src/index.jade',
+ dest: 'dist/index.jade'
+ }
+ }
+});
+```
+
+### Usage Examples
+
+> config
+
+```javascript
+grunt.initConfig({
+ inline: {
+ dist: {
+ src: 'src/index.html'
+ }
+ }
+});
+```
+
+>src/index.html
+
+```html
+
+
+ demo
+
+
+
+
+
+
+
+
+```
+
+after `grunt inline` was run, it will be something like
+
+```html
+
+
+ demo
+
+
+
+
+
+
+
+
+
+```
+
+#### inline tag
+
+Suppose there is an `` tag in `index.html` like bellow
+
+```html
+
+
+```
+
+The content of `test.html` is
+
+```html
+
I'm inline html
+hello world!
+```
+
+Then, after the `inline` task is run, the original content in `index.html` will be replaced with
+
+```html
+
I'm inline html
+hello world!
+```
+
+## Contributing
+
+In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).
+
+## Release History
+* 2019-12-20 v0.3.7 document optimized: markdown style problems of README
+* 2015-01-09 v0.3.3 bug fix: when processing files of a folder and then copy the processed content to another destination, the original files are changed unexpectedly, as mentioned in this issue [Support file globbing for input and output](https://github.com/chyingp/grunt-inline/issues/35)
+* 2014-06-16 v0.3.1 bug fix: protocol-relative urls in css are messed up
+* 2014-06-15 v0.3.1 bug fix: when options.tag is '', then all img tags, whose src attribute has already been inlined will be matched.
+* 2014-05-19 v0.3.0 support for new options.exts
+* 2014-05-19 v0.2.9 bug fix: options.tag is assigned '', bug image url in css are not converted to base64 formate
+* 2014-03-06 v0.2.6 bug fix: script tags like were not inlined
+* 2014-01-31 v0.2.3 radded tag option, encode url(..) images.
+* 2013-10-31 v0.2.2 bug fix: img urls like 'background: url(http://www.example.com/img/bg.png)' will be transformed to 'background: url(url(http://www.example.com/img/bg.png))'
+* 2013-10-30 v0.2.1 bug fix: when processing relative file path of img url in css stylesheet, forgot to transform "\" to "/" for windows users
+* 2013-10-30 v0.2.0 new feature: Support for minifing js、css when they ar inlined into html.
+* 2013-08-30 v0.1.9 bug fix: stylesheets ended with ">" cannot be inlined
+* 2013-09-02 v0.1.9 add feature: add options.dest to assign a destination path where the source file will be copied
+* 2013-09-02 v0.1.8 add feature: support for `` tag
diff --git a/build/plugins/grunt-inline/package.json b/build/plugins/grunt-inline/package.json
new file mode 100644
index 000000000..de233b24e
--- /dev/null
+++ b/build/plugins/grunt-inline/package.json
@@ -0,0 +1,40 @@
+{
+ "author": {
+ "name": "程序猿小卡",
+ "email": "chyingp@gmail.com",
+ "url": "https://github.com/chyingp"
+ },
+ "name": "grunt-inline",
+ "description": "Inlines img, script and link tags into the same file.",
+ "version": "0.3.7",
+ "keywords": [
+ "gruntplugin",
+ "inline",
+ "js",
+ "css"
+ ],
+ "main": "inline",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/chyingp/grunt-inline.git"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ },
+ "devDependencies": {
+ "grunt-contrib-nodeunit": "^4.0.0",
+ "grunt-contrib-clean": "^2.0.0",
+ "grunt-contrib-htmlmin": "^3.1.0",
+ "grunt": "^1.4.0"
+ },
+ "dependencies": {
+ "uglify-js": "^3.15.1",
+ "datauri": "^4.1.0",
+ "clean-css": "^5.2.4"
+ },
+ "scripts": {
+ "test": "grunt test"
+ },
+ "_id": "grunt-inline@0.1.0",
+ "_from": "grunt-inline@~0.1.0"
+}
diff --git a/build/plugins/grunt-inline/tasks/inline.js b/build/plugins/grunt-inline/tasks/inline.js
new file mode 100644
index 000000000..353623718
--- /dev/null
+++ b/build/plugins/grunt-inline/tasks/inline.js
@@ -0,0 +1,256 @@
+/*
+ * grunt-inline
+ * https://github.com/chyingp/grunt-inline
+ *
+ * Copyright (c) 2015 Auguest G. casper & IMWEB TEAM
+ */
+
+'use strict';
+
+module.exports = function(grunt) {
+
+ var path = require('path');
+ var datauri = require('datauri');
+ var UglifyJS = require("uglify-js");
+ var CleanCSS = require('clean-css');
+
+ grunt.registerMultiTask('inline', "Replaces , ';
+ }else{
+ grunt.log.error("Couldn't find " + inlineFilePath + '!');
+ }
+ }
+ grunt.log.debug('ret = : ' + ret +'\n');
+
+ return ret;
+
+ }).replace(//g, function(matchedWord, src){
+ var ret = matchedWord;
+
+ if(!isRemotePath(src) && src.indexOf(options.tag)!=-1){
+
+ var inlineFilePath = path.resolve( path.dirname(filepath), src ).replace(/\?.*$/, ''); // 将参数去掉
+
+ if( grunt.file.exists(inlineFilePath) ){
+ var styleSheetContent = grunt.file.read( inlineFilePath );
+ ret = '';
+ }else{
+ grunt.log.error("Couldn't find " + inlineFilePath + '!');
+ }
+ }
+ grunt.log.debug('ret = : ' + ret +'\n');
+
+ return ret;
+ }).replace(//g, function(matchedWord, src){
+ var ret = matchedWord;
+
+ if(!grunt.file.isPathAbsolute(src) && src.indexOf(options.tag)!=-1){
+
+ var inlineFilePath = path.resolve( path.dirname(filepath), src ).replace(/\?.*$/, ''); // 将参数去掉
+
+ if( grunt.file.exists(inlineFilePath) ){
+ ret = matchedWord.replace(src, (new datauri(inlineFilePath)).content);
+ }else{
+ grunt.log.error("Couldn't find " + inlineFilePath + '!');
+ }
+ }
+ grunt.log.debug('ret = : ' + ret +'\n');
+
+ return ret;
+ });
+
+ return fileContent;
+ }
+
+ function css(filepath, fileContent, relativeTo, options) {
+ if(relativeTo){
+ filepath = filepath.replace(/[^\/]+\//g, relativeTo);
+ }
+
+ fileContent = fileContent.replace(/url\(["']*([^)'"]+)["']*\)/g, function(matchedWord, imgUrl){
+ var newUrl = imgUrl;
+ var flag = imgUrl.indexOf(options.tag)!=-1; // urls like "img/bg.png?__inline" will be transformed to base64
+ if(isBase64Path(imgUrl) || isRemotePath(imgUrl)){
+ return matchedWord;
+ }
+ grunt.log.debug( 'imgUrl: '+imgUrl);
+ grunt.log.debug( 'filepath: '+filepath);
+ var absoluteImgurl = path.resolve( path.dirname(filepath),imgUrl );
+ grunt.log.debug( 'absoluteImgurl: '+absoluteImgurl);
+ newUrl = path.relative( path.dirname(filepath), absoluteImgurl );
+ grunt.log.debug( 'newUrl: '+newUrl);
+
+ absoluteImgurl = absoluteImgurl.replace(/\?.*$/, '');
+ if(flag && grunt.file.exists(absoluteImgurl)){
+ newUrl = datauri(absoluteImgurl);
+ }else{
+ newUrl = newUrl.replace(/\\/g, '/');
+ }
+
+ return matchedWord.replace(imgUrl, newUrl);
+ });
+ fileContent = options.cssmin ? CleanCSS.process(fileContent) : fileContent;
+
+ return fileContent;
+ }
+
+ function cssInlineToHtml(htmlFilepath, filepath, fileContent, relativeTo, options) {
+ if(relativeTo){
+ filepath = filepath.replace(/[^\/]+\//g, relativeTo);
+ }
+
+ fileContent = fileContent.replace(/url\(["']*([^)'"]+)["']*\)/g, function(matchedWord, imgUrl){
+ var newUrl = imgUrl;
+ var flag = !!imgUrl.match(/\?__inline/); // urls like "img/bg.png?__inline" will be transformed to base64
+ grunt.log.debug('flag:'+flag);
+ if(isBase64Path(imgUrl) || isRemotePath(imgUrl)){
+ return matchedWord;
+ }
+ grunt.log.debug( 'imgUrl: '+imgUrl);
+ grunt.log.debug( 'filepath: '+filepath);
+ var absoluteImgurl = path.resolve( path.dirname(filepath),imgUrl ); // img url relative to project root
+ grunt.log.debug( 'absoluteImgurl: '+absoluteImgurl);
+ newUrl = path.relative( path.dirname(htmlFilepath), absoluteImgurl ); // img url relative to the html file
+ grunt.log.debug([htmlFilepath, filepath, absoluteImgurl, imgUrl]);
+ grunt.log.debug( 'newUrl: '+newUrl);
+
+ absoluteImgurl = absoluteImgurl.replace(/\?.*$/, '');
+ if(flag && grunt.file.exists(absoluteImgurl)){
+ newUrl = datauri(absoluteImgurl);
+ }else{
+ newUrl = newUrl.replace(/\\/g, '/');
+ }
+
+ return matchedWord.replace(imgUrl, newUrl);
+ });
+ fileContent = options.cssmin ? CleanCSS.process(fileContent) : fileContent;
+
+ return fileContent;
+ }
+};
diff --git a/build/plugins/grunt-inline/test/dist/css.html b/build/plugins/grunt-inline/test/dist/css.html
new file mode 100644
index 000000000..6a100a3f2
--- /dev/null
+++ b/build/plugins/grunt-inline/test/dist/css.html
@@ -0,0 +1,13 @@
+
+
+
+ test
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/dist/css_greedy.html b/build/plugins/grunt-inline/test/dist/css_greedy.html
new file mode 100644
index 000000000..559d8cb04
--- /dev/null
+++ b/build/plugins/grunt-inline/test/dist/css_greedy.html
@@ -0,0 +1,9 @@
+
+
+
+ test
+
+
+
+
+
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/dist/html.html b/build/plugins/grunt-inline/test/dist/html.html
new file mode 100644
index 000000000..7f16e8817
--- /dev/null
+++ b/build/plugins/grunt-inline/test/dist/html.html
@@ -0,0 +1,10 @@
+
+
+
+ test
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/dist/html/test.html b/build/plugins/grunt-inline/test/dist/html/test.html
new file mode 100644
index 000000000..82571e1ef
--- /dev/null
+++ b/build/plugins/grunt-inline/test/dist/html/test.html
@@ -0,0 +1 @@
+
test
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/dist/html_greedy.html b/build/plugins/grunt-inline/test/dist/html_greedy.html
new file mode 100644
index 000000000..91b9466db
--- /dev/null
+++ b/build/plugins/grunt-inline/test/dist/html_greedy.html
@@ -0,0 +1,9 @@
+
+
+
+ test
+
+
+
+
+
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/dist/img.html b/build/plugins/grunt-inline/test/dist/img.html
new file mode 100644
index 000000000..242470447
--- /dev/null
+++ b/build/plugins/grunt-inline/test/dist/img.html
@@ -0,0 +1,10 @@
+
+
+
+ test
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/dist/img/icon.png b/build/plugins/grunt-inline/test/dist/img/icon.png
new file mode 100644
index 000000000..90c1ad9eb
Binary files /dev/null and b/build/plugins/grunt-inline/test/dist/img/icon.png differ
diff --git a/build/plugins/grunt-inline/test/dist/img_greedy.html b/build/plugins/grunt-inline/test/dist/img_greedy.html
new file mode 100644
index 000000000..998df9893
--- /dev/null
+++ b/build/plugins/grunt-inline/test/dist/img_greedy.html
@@ -0,0 +1,9 @@
+
+
+
+ test
+
+
+
+
+
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/dist/js/export.js b/build/plugins/grunt-inline/test/dist/js/export.js
new file mode 100644
index 000000000..c80ec0847
--- /dev/null
+++ b/build/plugins/grunt-inline/test/dist/js/export.js
@@ -0,0 +1 @@
+console.log('test');
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/dist/script.html b/build/plugins/grunt-inline/test/dist/script.html
new file mode 100644
index 000000000..6f58362cc
--- /dev/null
+++ b/build/plugins/grunt-inline/test/dist/script.html
@@ -0,0 +1,9 @@
+
+
+
+ test
+
+
+
+
+
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/dist/script_greedy.html b/build/plugins/grunt-inline/test/dist/script_greedy.html
new file mode 100644
index 000000000..b29fc603d
--- /dev/null
+++ b/build/plugins/grunt-inline/test/dist/script_greedy.html
@@ -0,0 +1,9 @@
+
+
+
+ test
+
+
+
+
+
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/dist/styles/main.css b/build/plugins/grunt-inline/test/dist/styles/main.css
new file mode 100644
index 000000000..7e5980010
--- /dev/null
+++ b/build/plugins/grunt-inline/test/dist/styles/main.css
@@ -0,0 +1,6 @@
+.main{border: none;}
+body{background: url(http://www.example.com/img/bg.png);}
+body{background: url('http://www.example.com/img/bg.png');}
+body{background: url('../img/icon.png?__inline=true');}
+body{background: url(data:image/jpeg;base64,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)
+body{background: url('data:image/jpeg;base64,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')
diff --git a/build/plugins/grunt-inline/test/expected/css.min.html b/build/plugins/grunt-inline/test/expected/css.min.html
new file mode 100644
index 000000000..8d3b73c2d
--- /dev/null
+++ b/build/plugins/grunt-inline/test/expected/css.min.html
@@ -0,0 +1,11 @@
+test
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/expected/css_greedy.min.html b/build/plugins/grunt-inline/test/expected/css_greedy.min.html
new file mode 100644
index 000000000..8d3b73c2d
--- /dev/null
+++ b/build/plugins/grunt-inline/test/expected/css_greedy.min.html
@@ -0,0 +1,11 @@
+test
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/expected/html.min.html b/build/plugins/grunt-inline/test/expected/html.min.html
new file mode 100644
index 000000000..09bc36da3
--- /dev/null
+++ b/build/plugins/grunt-inline/test/expected/html.min.html
@@ -0,0 +1 @@
+test
test
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/expected/html_greedy.min.html b/build/plugins/grunt-inline/test/expected/html_greedy.min.html
new file mode 100644
index 000000000..2ade75dd1
--- /dev/null
+++ b/build/plugins/grunt-inline/test/expected/html_greedy.min.html
@@ -0,0 +1 @@
+test
test
test
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/expected/img.min.html b/build/plugins/grunt-inline/test/expected/img.min.html
new file mode 100644
index 000000000..75c60c1ac
--- /dev/null
+++ b/build/plugins/grunt-inline/test/expected/img.min.html
@@ -0,0 +1 @@
+test
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/expected/img_greedy.min.html b/build/plugins/grunt-inline/test/expected/img_greedy.min.html
new file mode 100644
index 000000000..797808cd8
--- /dev/null
+++ b/build/plugins/grunt-inline/test/expected/img_greedy.min.html
@@ -0,0 +1 @@
+test
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/expected/script.min.html b/build/plugins/grunt-inline/test/expected/script.min.html
new file mode 100644
index 000000000..90da34278
--- /dev/null
+++ b/build/plugins/grunt-inline/test/expected/script.min.html
@@ -0,0 +1 @@
+test
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/expected/script_greedy.min.html b/build/plugins/grunt-inline/test/expected/script_greedy.min.html
new file mode 100644
index 000000000..9a49bd9e6
--- /dev/null
+++ b/build/plugins/grunt-inline/test/expected/script_greedy.min.html
@@ -0,0 +1 @@
+test
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/greedy_test.js b/build/plugins/grunt-inline/test/greedy_test.js
new file mode 100644
index 000000000..24c43a210
--- /dev/null
+++ b/build/plugins/grunt-inline/test/greedy_test.js
@@ -0,0 +1,48 @@
+var grunt = require('grunt');
+var fs = require('fs');
+
+function readFile(file) {
+ 'use strict';
+
+ var contents = grunt.file.read(file);
+
+ if (process.platform === 'win32') {
+ contents = contents.replace(/\r\n/g, '\n');
+ }
+
+ return contents;
+}
+
+function assertFileEquality(test, pathToActual, pathToExpected, message) {
+ var actual = readFile(pathToActual);
+ var expected = readFile(pathToExpected);
+ test.equal(expected, actual, message);
+}
+
+exports.inline = function(test) {
+ 'use strict';
+
+ test.expect(4);
+
+ assertFileEquality(test,
+ 'tmp/img_greedy.min.html',
+ 'test/expected/img_greedy.min.html',
+ 'Should compile two image target without newline characters');
+
+ assertFileEquality(test,
+ 'tmp/css_greedy.min.html',
+ 'test/expected/css_greedy.min.html',
+ 'Should compile two link target without newline characters');
+
+ assertFileEquality(test,
+ 'tmp/html_greedy.min.html',
+ 'test/expected/html_greedy.min.html',
+ 'Should compile two inline target without newline characters');
+
+ assertFileEquality(test,
+ 'tmp/script_greedy.min.html',
+ 'test/expected/script_greedy.min.html',
+ 'Should compile two script target without newline characters');
+
+ test.done();
+};
\ No newline at end of file
diff --git a/build/plugins/grunt-inline/test/inline_test.js b/build/plugins/grunt-inline/test/inline_test.js
new file mode 100644
index 000000000..f8dc6f22e
--- /dev/null
+++ b/build/plugins/grunt-inline/test/inline_test.js
@@ -0,0 +1,48 @@
+var grunt = require('grunt');
+var fs = require('fs');
+
+function readFile(file) {
+ 'use strict';
+
+ var contents = grunt.file.read(file);
+
+ if (process.platform === 'win32') {
+ contents = contents.replace(/\r\n/g, '\n');
+ }
+
+ return contents;
+}
+
+function assertFileEquality(test, pathToActual, pathToExpected, message) {
+ var actual = readFile(pathToActual);
+ var expected = readFile(pathToExpected);
+ test.equal(expected, actual, message);
+}
+
+exports.inline = function(test) {
+ 'use strict';
+
+ test.expect(4);
+
+ assertFileEquality(test,
+ 'tmp/css.min.html',
+ 'test/expected/css.min.html',
+ 'Should compile css inline');
+
+ assertFileEquality(test,
+ 'tmp/img.min.html',
+ 'test/expected/img.min.html',
+ 'Should compile image inline');
+
+ assertFileEquality(test,
+ 'tmp/html.min.html',
+ 'test/expected/html.min.html',
+ 'Should compile html inline');
+
+ assertFileEquality(test,
+ 'tmp/script.min.html',
+ 'test/expected/script.min.html',
+ 'Should compile script inline');
+
+ test.done();
+};
\ No newline at end of file