Skip to content

Commit

Permalink
Merge pull request #90 from nitinhayaran/master
Browse files Browse the repository at this point in the history
replaceRequireScript fix for conditional html in head and for templates
  • Loading branch information
asciidisco committed Mar 2, 2014
2 parents e869e59 + 78a3ec5 commit e06d518
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 30 deletions.
56 changes: 29 additions & 27 deletions lib/replace.js
Expand Up @@ -11,9 +11,7 @@ exports.init = function(grunt) {

// External libs.
var Q = require('q');
var jsdom = require('jsdom');
var fs = require('fs');
var rBody = /<body>/;
var cheerio = require('cheerio');

return function(config) {
var deferred = Q.defer();
Expand All @@ -29,36 +27,40 @@ exports.init = function(grunt) {
var filesEvaluated = 0;

// iterate over found html files
files.forEach(function(file) {
var fileContents = fs.readFileSync(file, 'utf-8');
var hasBody = rBody.test(fileContents);
files.forEach(function (file) {
// load file contents
var contents = String(grunt.file.read(file, 'utf-8'));
// reference to script regex https://github.com/jquery/jquery/blob/1.7.2/src/ajax.js#L14
var script_re = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
matches = contents.match(script_re);

jsdom.env(fileContents, {
FetchExternalResources: false,
ProcessExternalResources: false
}, function(err, window) {
var scripts = window.document.querySelectorAll('script[data-main]');

[].slice.call(scripts).forEach(function(script) {
var insertScript = (file.modulePath || script.getAttribute('data-main'));
script.src = insertScript + '.js';
script.removeAttribute('data-main');
});

var html = hasBody ? window.document.innerHTML : window.document.body.innerHTML;
grunt.log.writeln('Updating requirejs script tag for file', file);
grunt.file.write(file, html);

// only resolve after all files have been evaluated
filesEvaluated++;
if (filesEvaluated >= files.length) {
deferred.resolve(config);
[].slice.call(matches).forEach(function(match, i){
var $ = cheerio.load(match),
elm = $('script');
if (elm.attr('data-main')){
var insertScript = (file.modulePath || elm.attr('data-main'));
elm.attr('src', insertScript + '.js');
elm.removeAttr('data-main');
// replace i'th occurrence in content
var j = 0;
contents = contents.replace(script_re, function(match){
j++;
return (j-1 === i) ? $.html() : match;
});
}
});

grunt.log.writeln('Updating requirejs script tag for file', file);
grunt.file.write(file, contents);
// only resolve after all files have been evaluated
filesEvaluated++;
if (filesEvaluated >= files.length) {
deferred.resolve(config);
}

});
});

return deferred.promise;
};
};

5 changes: 2 additions & 3 deletions package.json
Expand Up @@ -29,11 +29,10 @@
},
"dependencies": {
"requirejs": "2.1.x",
"cheerio": "0.10.x",
"cheerio": "0.13.x",
"almond": "0.2.x",
"gzip-js": "0.3.x",
"q": "0.8.x",
"jsdom": "0.8.x"
"q": "0.8.x"
},
"devDependencies": {
"grunt": "~0.4.0",
Expand Down
16 changes: 16 additions & 0 deletions test/fixtures/replaceConditionalComments.html
@@ -0,0 +1,16 @@
<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<title>Testing</title>
<!-- build:js scripts/vendor/modernizr.js -->
<script src="bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->
</head>
<body>
<script src="js/require.js" data-main="js/main"></script>
</body>
</html>
17 changes: 17 additions & 0 deletions test/fixtures/replaceInDjangoTemplates.html
@@ -0,0 +1,17 @@
{% load static %}
<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<title>Testing</title>
<!-- build:js scripts/vendor/modernizr.js -->
<script src="bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->
</head>
<body>
<script src="js/require.js" data-main="js/main"></script>
</body>
</html>
42 changes: 42 additions & 0 deletions test/require_test.js
Expand Up @@ -302,6 +302,48 @@ exports['require'] = {
result = grunt.file.read('node_modules/almond/almond.js');
test.ok(result.length > 0, 'original almond.js should still be there');
test.done();
},

'requirejs script tag should be replaced without messing with conditional html': function(test) {
'use strict';
test.expect(2);
var config = {
replaceRequireScript: [{
files: ['tmp/replaceConditionalComments.html'],
module: 'main'
}],
modules: [{name: 'main'}],
almond: true
};

grunt.file.copy('test/fixtures/replaceConditionalComments.html', 'tmp/replaceConditionalComments.html');
replaceAlmondInHtmlFiles(config).then(function() {
var replacedFileContents = grunt.file.read(config.replaceRequireScript[0].files[0]);
test.ok(replacedFileContents.search('<script src="js/main.js"></script>') > -1, 'should replace script tag ´src´ contents');
test.ok(replacedFileContents.search('<!--\\[if lt IE 7\\]>') > -1, 'should not mess with conditional html');
test.done();
});
},

'requirejs script tag should be replaced without altering django template tags': function(test) {
'use strict';
test.expect(2);
var config = {
replaceRequireScript: [{
files: ['tmp/replaceInDjangoTemplates.html'],
module: 'main'
}],
modules: [{name: 'main'}],
almond: true
};

grunt.file.copy('test/fixtures/replaceInDjangoTemplates.html', 'tmp/replaceInDjangoTemplates.html');
replaceAlmondInHtmlFiles(config).then(function() {
var replacedFileContents = grunt.file.read(config.replaceRequireScript[0].files[0]);
test.ok(replacedFileContents.search('<script src="js/main.js"></script>') > -1, 'should replace script tag ´src´ contents');
test.ok(replacedFileContents.search('{% load static %}') > -1, 'should not mess with conditional html');
test.done();
});
}

};

0 comments on commit e06d518

Please sign in to comment.