Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for issue #1, <meta> being before doctype #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 30 additions & 13 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
'use strict';

var doctypeRe = new RegExp(/^<!doctype[^>]*>\n?/im);
var metaTagRe = new RegExp(/^<meta[^>]*>?/igm);

function hashof(string) {
var hash = 0;
Expand All @@ -31,13 +32,26 @@
return hash.toString(16);
}

function insert(source, needle, value) {
function stripMetaTags(meta) {
if (meta) {
var replaced = meta.replace(metaTagRe, '').trim() + '\n';
return replaced;
}
return meta;
}

function insert(source, needle, value, after) {
if (source.toLowerCase().indexOf(needle.toLowerCase()) === -1) {
return null;
}

var left = source.substring(0, source.toLowerCase().lastIndexOf(needle.toLowerCase()));
var right = source.substring(source.toLowerCase().lastIndexOf(needle.toLowerCase()));
var left = after
? source.substring(0, source.toLowerCase().lastIndexOf(needle.toLowerCase()) + needle.length)
: source.substring(0, source.toLowerCase().lastIndexOf(needle.toLowerCase()));
var right = after
? source.substring(source.toLowerCase().lastIndexOf(needle.toLowerCase()) + needle.length)
: source.substring(source.toLowerCase().lastIndexOf(needle.toLowerCase()));

var result = '';

if (left && right) {
Expand Down Expand Up @@ -127,16 +141,19 @@
}
}

// only look for a doctype at the top of the document
var doctype = (html.trim().split('\n').shift().trim().match(doctypeRe) || [])[0] || '';

if (doctype) {
file = file.replace(doctypeRe, doctype + '\n' + meta);
// strip from original html
} else {
file = meta + file;
}

// Check for head tags
if (file.toLowerCase().indexOf("<head>") !== -1 && meta) {
file = insert(file, "<head>", meta, true);
} else if (meta) { // there is no head, but there is meta
// only look for a doctype at the top of the document
var doctype = (html.trim().split('\n').shift().trim().match(doctypeRe) || [])[0] || '';
if (doctype) {
// put †ry to strip out any meta tags that exist in the meta string
file = file.replace(doctypeRe, doctype + '\n' + stripMetaTags(meta));
} else {
file = stripMetaTags(meta) + file;
}
}

if (javascript) {
if (file.indexOf('%code%') !== -1) {
Expand Down
5 changes: 5 additions & 0 deletions test/fixtures/no-doctype-no-head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<html>
<body>
<p>Nicely done sir.</p>
</body>
</html>
6 changes: 6 additions & 0 deletions test/fixtures/no-head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<!DOCTYPE html>
<html>
<body>
<p>Nicely done sir.</p>
</body>
</html>
83 changes: 83 additions & 0 deletions test/meta.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
'use strict';
/*global describe, it, beforeEach */
var assert = require('assert');
var toFile = require('../');
var fs = require('fs');
var path = require('path');
var cheerio = require('cheerio');

describe('meta', function () {

it('should be inserted in the head, if head tag exists', function () {
var html = fs.readFileSync(path.join(__dirname, 'fixtures', 'simple.html'), 'utf8');

var file = toFile({ html: html, meta: '<meta name="robots" content="noindex" />' });

var $ = cheerio.load(file);
assert($('head meta[name=robots]').length === 1, 'meta tag not found');
});

it('should be inserted in the head, when head tag exists and no doctype', function () {
var html = fs.readFileSync(path.join(__dirname, 'fixtures', 'no-doctype.html'), 'utf8');

var file = toFile({ html: html, meta: '<meta name="robots" content="noindex" />' });

var $ = cheerio.load(file);
assert($('head meta[name=robots]').length === 1, 'meta tag not found');
});

it('should not change content if there is no meta specified', function () {
var html = fs.readFileSync(path.join(__dirname, 'fixtures', 'simple.html'), 'utf8');

var file = toFile({ html: html});

assert(html === file, 'files should match');
});

it('should be prepended to file when no doctype and no head', function () {
var meta = '<!-- Meta Comment -->';
var html = fs.readFileSync(path.join(__dirname, 'fixtures', 'no-doctype-no-head.html'), 'utf8');

var file = toFile({ html: html, meta: meta});

var header = file.substring(0, file.indexOf('<html>')).trim();
assert(header === meta, 'header was not prepended to file');
});

it('should be prepended with <meta> tags stripped content to file when no doctype and head', function () {
var metaComment = '<!-- Meta Comment -->';
var metaTag = '<meta name="robots" content="noindex" />\n<meta name="robots" content="noindex" />';
var html = fs.readFileSync(path.join(__dirname, 'fixtures', 'no-doctype-no-head.html'), 'utf8');

var file = toFile({ html: html, meta: metaComment + '\n' + metaTag});

var header = file.substring(0, file.indexOf('<html>')).trim();
assert(header === metaComment, 'header was not prepended to file');
});

it('should be placed after doctype when doctype exists and no head', function () {
var doctype = '<!DOCTYPE html>';
var meta = '<!-- Meta Comment -->';
var html = fs.readFileSync(path.join(__dirname, 'fixtures', 'no-head.html'), 'utf8');

var file = toFile({ html: html, meta: meta});

var doctypeEnd = file.lastIndexOf(doctype) + doctype.length;
var header = file.substring(doctypeEnd, file.indexOf('<html>')).trim();
assert(header === meta, 'header was not prepended to file');
});

it('should be placed after doctype and have meta tags stripped when doctype exists and no head', function () {
var doctype = '<!DOCTYPE html>';
var metaComment = '<!-- Meta Comment -->';
var metaTag = '<meta name="robots" content="noindex" />\n<meta name="robots" content="noindex" />';
var html = fs.readFileSync(path.join(__dirname, 'fixtures', 'no-head.html'), 'utf8');

var file = toFile({ html: html, meta: metaComment + '\n' + metaTag});

var doctypeEnd = file.lastIndexOf(doctype) + doctype.length;
var header = file.substring(doctypeEnd, file.indexOf('<html>')).trim();
assert(header === metaComment, 'header was not prepended to file');
});

});