html-uglify
Advanced tools
Comparing version 1.1.3 to 1.2.0
201
lib/main.js
@@ -9,3 +9,2 @@ 'use strict'; | ||
var VERSION = require('../package.json').version; | ||
var LOOKUP_DELIMITER = '='; | ||
@@ -22,12 +21,47 @@ function HTMLUglify(config) { | ||
HTMLUglify.prototype.determinePointer = function(type, value, lookups) { | ||
var lookupKey = [type, value].join(LOOKUP_DELIMITER); | ||
var existingPointer = lookups[lookupKey]; | ||
HTMLUglify.prototype.checkForStandardPointer = function(lookups, type, value) { | ||
return lookups[type] && lookups[type][value]; | ||
}; | ||
if (existingPointer) { | ||
return existingPointer; | ||
HTMLUglify.prototype.checkForAttributePointer = function(lookups, type, value) { | ||
var pointer; | ||
var typeLookups = lookups[type] || {}; | ||
var keys = Object.keys(typeLookups); | ||
keys.forEach(function(key) { | ||
if (value.indexOf(key) !== -1) { | ||
pointer = value.replace(key, typeLookups[key]); | ||
} | ||
}); | ||
return pointer; | ||
}; | ||
HTMLUglify.prototype.generatePointer = function(lookups) { | ||
var idCount = Object.keys(lookups['id'] || {}).length; | ||
var classCount = Object.keys(lookups['class'] || {}).length; | ||
var counter = idCount + classCount; | ||
return this.hashids.encode(counter); | ||
}; | ||
HTMLUglify.prototype.pointer = function(type, value, lookups) { | ||
return this.checkForStandardPointer(lookups, type, value) || | ||
this.checkForAttributePointer(lookups, type, value) || | ||
this.generatePointer(lookups); | ||
}; | ||
HTMLUglify.prototype.insertLookup = function(type, value, pointer, lookups) { | ||
if (!lookups[type]) { | ||
lookups[type] = {}; | ||
} | ||
lookups[type][value] = pointer; | ||
}; | ||
var counter = Object.keys(lookups).length; | ||
var pointer = this.hashids.encode(counter); | ||
HTMLUglify.prototype.createLookup = function(type, value, lookups) { | ||
var pointer; | ||
if (value && !this.isWhitelisted(type, value)) { | ||
pointer = this.pointer(type, value, lookups); | ||
this.insertLookup(type, value, pointer, lookups); | ||
} | ||
return pointer; | ||
@@ -52,14 +86,14 @@ }; | ||
HTMLUglify.prototype.pointerizeClass = function($element, lookups) { | ||
var _this = this; | ||
var self = this; | ||
var value = $element.attr('class'); | ||
if (value && !this.isWhitelisted('class', value)) { | ||
if (value) { | ||
var splitClasses = value.split(/\s+/); | ||
splitClasses.forEach(function(value) { | ||
var pointer = _this.determinePointer('class', value, lookups); | ||
$element.removeClass(value); | ||
$element.addClass(pointer); | ||
_this.populateLookups('class', value, pointer, lookups); | ||
var pointer = self.createLookup('class', value, lookups); | ||
if (pointer) { | ||
$element.removeClass(value); | ||
$element.addClass(pointer); | ||
} | ||
}); | ||
@@ -72,44 +106,10 @@ } | ||
if (value && !this.isWhitelisted('id', value)) { | ||
var pointer = this.determinePointer('id', value, lookups); | ||
var pointer = this.createLookup('id', value, lookups); | ||
if (pointer) { | ||
$element.attr(type, pointer); | ||
this.populateLookups('id', value, pointer, lookups); // always set to id for lookups | ||
} | ||
}; | ||
HTMLUglify.prototype.populateLookups = function(type, value, pointer, lookups) { | ||
var key = [type, value].join(LOOKUP_DELIMITER); | ||
lookups[key] = pointer; | ||
}; | ||
HTMLUglify.prototype.rewriteElements = function($, lookups) { | ||
var _this = this; | ||
lookups = lookups || {}; | ||
$('*[id]').each(function() { | ||
_this.pointerizeIdAndFor('id', $(this), lookups); | ||
}); | ||
$('*[for]').each(function() { | ||
_this.pointerizeIdAndFor('for', $(this), lookups); | ||
}); | ||
$('*[class]').each(function() { | ||
_this.pointerizeClass($(this), lookups); | ||
}); | ||
return $; | ||
}; | ||
HTMLUglify.prototype.setNewSelector = function(lead, rule, toReplace, pointer) { | ||
toReplace = [lead, toReplace].join(''); | ||
pointer = [lead, pointer].join(''); | ||
var newSelector = rule.selector.replace(toReplace, pointer); | ||
rule.selector = newSelector; | ||
}; | ||
HTMLUglify.prototype.processRules = function(rules, lookups) { | ||
var _this = this; | ||
var self = this; | ||
@@ -119,45 +119,58 @@ rules.forEach(function(rule) { | ||
if (rule.type === 'atrule' && rule.name === 'media') { | ||
_this.processRules(rule.nodes, lookups); | ||
self.processRules(rule.nodes, lookups); | ||
} else if (rule.type === 'rule') { | ||
var selectorParts = rule.selector.split(/ |\:not\(|\)|\>|\~|\+|\:\:|\:checked|\:after|\:before|\:root|\:|\[|\]|(?=\s*\.)|(?=\s*\#)|\,/); | ||
selectorParts.forEach(function(selectorPart) { | ||
var keyLookup = ''; | ||
var toReplace; | ||
var parts = rule.selector.split(/ |\:not\(|\)|\>|\~|\+|\:\:|\:checked|\:after|\:before|\:root|\:|\[|\]|(?=\s*\.)|(?=\s*\#)|\,/); | ||
parts.forEach(function(part) { | ||
var pointer; | ||
var value; | ||
// handle #something | ||
if (selectorPart.indexOf('#') > -1) { | ||
toReplace = selectorPart.replace(/\#/g, ''); | ||
keyLookup = ['id', toReplace].join(LOOKUP_DELIMITER); | ||
if (part.indexOf('#') > -1) { | ||
value = part.replace(/\#/g, ''); | ||
pointer = self.createLookup('id', value, lookups); | ||
} | ||
// handle .something | ||
if (selectorPart.indexOf('.') > -1) { | ||
toReplace = selectorPart.replace(/\./g, ''); | ||
keyLookup = ['class', toReplace].join(LOOKUP_DELIMITER); | ||
if (part.indexOf('.') > -1) { | ||
value = part.replace(/\./g, ''); | ||
pointer = self.createLookup('class', value, lookups); | ||
} | ||
// handle *[id=something] | ||
if (selectorPart.indexOf('id=') > -1){ | ||
toReplace = selectorPart.replace(/id=/g, '').replace(/\"/g, ''); // remove quotes from "somevalue" | ||
keyLookup = ['id', toReplace].join(LOOKUP_DELIMITER); | ||
// handle *[id=something] or *[id*=something] | ||
if ( | ||
part.indexOf('id=') > -1 || | ||
part.indexOf('id*=') > -1 || | ||
part.indexOf('id^=') > -1 || | ||
part.indexOf('id$=') > -1 | ||
) { | ||
value = part.replace(/id[\*\^\$]?=|\"|\'/g, ''); | ||
pointer = self.createLookup('id', value, lookups); | ||
} | ||
// handle *[class=something] | ||
if (selectorPart.indexOf('class=') > -1) { | ||
toReplace = selectorPart.replace(/class=/g, ''); | ||
keyLookup = ['class', toReplace].join(LOOKUP_DELIMITER); | ||
// handle *[class=something] or *[class*=something] | ||
if ( | ||
part.indexOf('class=') > -1 || | ||
part.indexOf('class*=') > -1 || | ||
part.indexOf('class^=') > -1 || | ||
part.indexOf('class$=') > -1 | ||
) { | ||
value = part.replace(/class[\*\^\$]?=|\"|\'/g, ''); | ||
pointer = self.createLookup('class', value, lookups); | ||
} | ||
// handle *[for=something] | ||
if (selectorPart.indexOf('for=') > -1){ | ||
toReplace = selectorPart.replace(/for=/g, ''); | ||
toReplace = toReplace.replace(/\"/g, ''); // remove quotes from "somevalue" | ||
keyLookup = ['id', toReplace].join(LOOKUP_DELIMITER); | ||
// handle *[for=something] or *[for*=something] | ||
if ( | ||
part.indexOf('for=') > -1 || | ||
part.indexOf('for*=') > -1 || | ||
part.indexOf('for^=') > -1 || | ||
part.indexOf('for$=') > -1 | ||
) { | ||
value = part.replace(/for[\*\^\$]?=|\"|\'/g, ''); | ||
pointer = self.createLookup('id', value, lookups); | ||
} | ||
var pointer = lookups[keyLookup]; | ||
if (pointer) { | ||
var regex = new RegExp('(?!^)' + toReplace); // negative look ahead to avoid start of the string | ||
var newSelectorPart = selectorPart.replace(regex, pointer); | ||
var newSelector = rule.selector.replace(selectorPart, newSelectorPart); | ||
var regex = new RegExp('(?!^)' + value); // negative look ahead to avoid start of the string | ||
var newSelectorPart = part.replace(regex, pointer); | ||
var newSelector = rule.selector.replace(part, newSelectorPart); | ||
rule.selector = newSelector; | ||
@@ -170,4 +183,24 @@ } | ||
HTMLUglify.prototype.rewriteElements = function($, lookups) { | ||
var self = this; | ||
lookups = lookups || {}; | ||
$('*[id]').each(function() { | ||
self.pointerizeIdAndFor('id', $(this), lookups); | ||
}); | ||
$('*[for]').each(function() { | ||
self.pointerizeIdAndFor('for', $(this), lookups); | ||
}); | ||
$('*[class]').each(function() { | ||
self.pointerizeClass($(this), lookups); | ||
}); | ||
return $; | ||
}; | ||
HTMLUglify.prototype.rewriteStyles = function($, lookups) { | ||
var _this = this; | ||
var self = this; | ||
@@ -179,3 +212,3 @@ lookups = lookups || {}; | ||
var ast = postcssSafeParser($style.text()); | ||
_this.processRules(ast.nodes, lookups); | ||
self.processRules(ast.nodes, lookups); | ||
$style.text(ast.toString()); | ||
@@ -191,4 +224,4 @@ }); | ||
var $ = cheerio.load(html); | ||
$ = this.rewriteStyles($, lookups); | ||
$ = this.rewriteElements($, lookups); | ||
$ = this.rewriteStyles($, lookups); | ||
@@ -195,0 +228,0 @@ return $.html(); |
{ | ||
"name": "html-uglify", | ||
"version": "1.1.3", | ||
"version": "1.2.0", | ||
"description": "Uglifies an HTML file and its associated CSS for compression. Great for HTML emails!", | ||
"main": "lib/main.js", | ||
"scripts": { | ||
"test": "mocha test/main.js" | ||
"test": "mocha test/main.js", | ||
"bench": "node test/benchmark.js" | ||
}, | ||
@@ -25,2 +26,3 @@ "keywords": [ | ||
"devDependencies": { | ||
"benchmark": "^1.0.0", | ||
"chai": "^3.4.1", | ||
@@ -27,0 +29,0 @@ "mocha": "^2.3.4" |
# html-uglify | ||
[![Build Status](https://travis-ci.org/Rebelmail/html-uglify.svg?branch=master)](https://travis-ci.org/Rebelmail/html-uglify) | ||
[![NPM version](https://badge.fury.io/js/html-uglify.png)](http://badge.fury.io/js/html-uglify) | ||
![html-uglify](../master/html-uglify.png?raw=true) | ||
@@ -9,5 +12,2 @@ | ||
[![BuildStatus](https://travis-ci.org/RebelMail/html-uglify.png?branch=master)](https://travis-ci.org/RebelMail/html-uglify) | ||
[![NPM version](https://badge.fury.io/js/html-uglify.png)](http://badge.fury.io/js/html-uglify) | ||
```javascript | ||
@@ -21,3 +21,3 @@ var HTMLUglify = require('html-uglify'); | ||
``` | ||
```sh | ||
npm install html-uglify --save | ||
@@ -41,3 +41,3 @@ ``` | ||
1. Fork it | ||
2. Create your feature branch (`git checkout -b my-new-feature`) | ||
2. Create your feature branch | ||
3. Commit your changes (`git commit -am 'Added some feature'`) | ||
@@ -49,5 +49,5 @@ 4. Push to the branch (`git push origin my-new-feature`) | ||
``` | ||
```sh | ||
npm install | ||
npm test | ||
``` |
318
test/main.js
@@ -19,22 +19,127 @@ 'use strict'; | ||
it('returns true if id is in whitelist', function() { | ||
var whitelisted = htmlUglify.isWhitelisted('id', 'theid') | ||
var whitelisted = htmlUglify.isWhitelisted('id', 'theid'); | ||
assert.isTrue(whitelisted); | ||
}); | ||
it('returns false if id is in the whitelist but only checking for classes', function() { | ||
var whitelisted = htmlUglify.isWhitelisted('class', 'theid') | ||
var whitelisted = htmlUglify.isWhitelisted('class', 'theid'); | ||
assert.isFalse(whitelisted); | ||
}); | ||
it('returns true if class is in whitelist', function() { | ||
var whitelisted = htmlUglify.isWhitelisted('class', 'theclass') | ||
var whitelisted = htmlUglify.isWhitelisted('class', 'theclass'); | ||
assert.isTrue(whitelisted); | ||
}); | ||
it('returns true if id is in whitelist for a unicode character', function() { | ||
var whitelisted = htmlUglify.isWhitelisted('id', '★') | ||
var whitelisted = htmlUglify.isWhitelisted('id', '★'); | ||
assert.isTrue(whitelisted); | ||
}); | ||
it('returns true if class is in whitelist for a unicode character', function() { | ||
var whitelisted = htmlUglify.isWhitelisted('class', '★') | ||
var whitelisted = htmlUglify.isWhitelisted('class', '★'); | ||
assert.isTrue(whitelisted); | ||
}); | ||
}); | ||
describe('#checkForStandardPointer', function() { | ||
it('returns undefined when name not found', function() { | ||
var lookups = { | ||
'class': { 'something': 'zzz' } | ||
}; | ||
var value = 'other'; | ||
var pointer = htmlUglify.checkForStandardPointer(lookups, 'class', value); | ||
assert.isUndefined(pointer); | ||
}); | ||
it('returns pointer when found', function() { | ||
var lookups = { | ||
'class': { 'something': 'zzz' } | ||
}; | ||
var value = 'something'; | ||
var pointer = htmlUglify.checkForStandardPointer(lookups, 'class', value); | ||
assert.equal(pointer, 'zzz'); | ||
}); | ||
}); | ||
describe('#checkForAttributePointer', function() { | ||
it('returns undefined when not found', function() { | ||
var lookups = { | ||
'class': { 'something': 'zzz' } | ||
}; | ||
var value = 'other'; | ||
var pointer = htmlUglify.checkForAttributePointer(lookups, 'class', value); | ||
assert.isUndefined(pointer); | ||
}); | ||
it('returns the pointer when value contains same string as an existing lookup', function() { | ||
var lookups = { | ||
'class': { 'something': 'zzz' } | ||
}; | ||
var value = 'somethingElse'; | ||
var pointer = htmlUglify.checkForAttributePointer(lookups, 'class', value); | ||
assert.equal(pointer, 'zzzElse'); | ||
}); | ||
}); | ||
describe('#generatePointer', function() { | ||
it('returns xz for counter 0 lookups', function() { | ||
var lookups = {}; | ||
var pointer = htmlUglify.generatePointer(lookups); | ||
assert.equal(pointer, 'xz'); | ||
}); | ||
it('returns wk for 1 lookups', function() { | ||
var lookups = { 'id': { 'a': 'xz' } }; | ||
var pointer = htmlUglify.generatePointer(lookups); | ||
assert.equal(pointer, 'wk'); | ||
}); | ||
it('returns en for 2 lookups', function() { | ||
var lookups = { 'id': { 'a': 'xz' }, 'class': { 'b': 'wk' } }; | ||
var pointer = htmlUglify.generatePointer(lookups); | ||
assert.equal(pointer, 'en'); | ||
}); | ||
}); | ||
describe('#pointer', function() { | ||
it('generates a new pointer', function() { | ||
var lookups = {}; | ||
var pointer = htmlUglify.pointer('class', 'newClass', {}); | ||
assert.equal(pointer, 'xz', lookups); | ||
}); | ||
it('generates a new pointer given a different one exists', function() { | ||
var lookups = { | ||
'class': { 'otherClass': 'wk' } | ||
}; | ||
var pointer = htmlUglify.pointer('class', 'newClass', lookups); | ||
assert.equal(pointer, 'wk', lookups); | ||
}); | ||
it('generates a new pointer given a different one exists in a different attribute', function() { | ||
var lookups = { | ||
'id': { 'someId': 'wk' } | ||
}; | ||
var pointer = htmlUglify.pointer('class', 'newClass', lookups); | ||
assert.equal(pointer, 'wk', lookups); | ||
}); | ||
it('finds an existing class pointer', function() { | ||
var lookups = { | ||
'class': { 'someClass': 'xz' } | ||
}; | ||
var pointer = htmlUglify.pointer('class', 'someClass', lookups); | ||
assert.equal(pointer, 'xz', lookups); | ||
}); | ||
it('finds an existing id pointer', function() { | ||
var lookups = { | ||
'id': { 'someId': 'en' } | ||
}; | ||
var pointer = htmlUglify.pointer('id', 'someId', lookups); | ||
assert.equal(pointer, 'en'); | ||
}); | ||
it('finds a more complex existing pointer', function() { | ||
var lookups = { | ||
class: { | ||
test: 'xz', | ||
testOther: 'wk', | ||
otratest: 'en' | ||
} | ||
}; | ||
var pointer = htmlUglify.pointer('class', 'test', lookups); | ||
assert.equal(pointer, 'xz'); | ||
}); | ||
}); | ||
describe('#rewriteStyles', function() { | ||
@@ -48,11 +153,11 @@ it('rewrites an id given lookups', function() { | ||
}); | ||
it('does not rewrite an id given no lookups', function() { | ||
it('rewrites an id', function() { | ||
var lookups = { }; | ||
var html = '<style>#abe{ color: red; }</style>'; | ||
var html = '<style>#xz{ color: red; }</style>'; | ||
var $ = cheerio.load(html); | ||
var results = htmlUglify.rewriteStyles($, lookups).html(); | ||
assert.equal(results, '<style>#abe{ color: red; }</style>'); | ||
assert.equal(results, '<style>#xz{ color: red; }</style>'); | ||
}); | ||
it('rewrites an id with the same name as the element', function() { | ||
var lookups = { 'id=label': 'ab' }; | ||
var lookups = {'id': {'label': 'ab' }}; | ||
var html = '<style>label#label{ color: blue; }</style>'; | ||
@@ -64,3 +169,3 @@ var $ = cheerio.load(html); | ||
it('rewrites a for= given lookups', function() { | ||
var lookups = { 'id=email': 'ab' }; | ||
var lookups = { 'id': {'email': 'ab'} }; | ||
var html = '<style>label[for=email]{ color: blue; }</style>'; | ||
@@ -71,3 +176,3 @@ var $ = cheerio.load(html); | ||
}); | ||
it('does not rewrite a for= given no lookups', function() { | ||
it('does rewrites a for=', function() { | ||
var lookups = {}; | ||
@@ -77,6 +182,6 @@ var html = '<style>label[for=email]{ color: blue; }</style>'; | ||
var results = htmlUglify.rewriteStyles($, lookups).html(); | ||
assert.equal(results, "<style>label[for=email]{ color: blue; }</style>"); | ||
assert.equal(results, "<style>label[for=xz]{ color: blue; }</style>"); | ||
}); | ||
it('rewrites a for= with quotes given lookups', function() { | ||
var lookups = { 'id=email': 'ab' }; | ||
var lookups = { 'id': {'email': 'ab'} }; | ||
var html = '<style>label[for="email"]{ color: blue; }</style>'; | ||
@@ -88,3 +193,3 @@ var $ = cheerio.load(html); | ||
it('rewrites a for= with the same name as the element', function() { | ||
var lookups = { 'id=label': 'ab' }; | ||
var lookups = { 'id': { 'label': 'ab' }}; | ||
var html = '<style>label[for="label"]{ color: blue; }</style>'; | ||
@@ -96,3 +201,3 @@ var $ = cheerio.load(html); | ||
it('rewrites an id= given lookups', function() { | ||
var lookups = { 'id=email': 'ab' }; | ||
var lookups = { 'id': {'email': 'ab'} }; | ||
var html = '<style>label[id=email]{ color: blue; }</style>'; | ||
@@ -104,3 +209,3 @@ var $ = cheerio.load(html); | ||
it('rewrites an id= with quotes given lookups', function() { | ||
var lookups = { 'id=email': 'ab' }; | ||
var lookups = { 'id': { 'email': 'ab' } }; | ||
var html = '<style>label[id="email"]{ color: blue; }</style>'; | ||
@@ -112,3 +217,3 @@ var $ = cheerio.load(html); | ||
it('rewrites an id= with quotes and with the same name as the element', function() { | ||
var lookups = { 'id=label': 'ab' }; | ||
var lookups = { 'id': {'label': 'ab'} }; | ||
var html = '<style>label[id="label"]{ color: blue; }</style>'; | ||
@@ -120,3 +225,3 @@ var $ = cheerio.load(html); | ||
it('rewrites a class given lookups', function() { | ||
var lookups = { 'class=email': 'ab' }; | ||
var lookups = { 'class': { 'email': 'ab' }}; | ||
var html = '<style>label.email{ color: blue; }</style>'; | ||
@@ -128,3 +233,3 @@ var $ = cheerio.load(html); | ||
it('rewrites a class with the same name as the element', function() { | ||
var lookups = { 'class=label': 'ab' }; | ||
var lookups = { 'class': { 'label': 'ab' }}; | ||
var html = '<style>label.label{ color: blue; }</style>'; | ||
@@ -136,3 +241,3 @@ var $ = cheerio.load(html); | ||
it('rewrites a class= given lookups', function() { | ||
var lookups = { 'class=email': 'ab' }; | ||
var lookups = { 'class': { 'email': 'ab' }}; | ||
var html = '<style>form [class=email] { color: blue; }</style>'; | ||
@@ -144,3 +249,3 @@ var $ = cheerio.load(html); | ||
it('rewrites multi-selector rule', function() { | ||
var lookups = { 'class=email': 'ab' }; | ||
var lookups = { 'class': { 'email': 'ab' }}; | ||
var html = '<style>label.email, a.email { color: blue; }</style>'; | ||
@@ -152,3 +257,3 @@ var $ = cheerio.load(html); | ||
it('rewrites css media queries', function() { | ||
var lookups = { 'id=abe': 'wz' }; | ||
var lookups = { 'id': { 'abe': 'wz' }}; | ||
@@ -161,3 +266,3 @@ var html = '<style>@media screen and (max-width: 300px) { #abe{ color: red; } }</style>'; | ||
it('rewrites nested css media queries', function() { | ||
var lookups = { 'id=abe': 'wz' }; | ||
var lookups = { 'id': { 'abe': 'wz' }}; | ||
@@ -173,6 +278,60 @@ var html = '<style>@media { @media screen and (max-width: 300px) { #abe{ color: red; } } }</style>'; | ||
var results = htmlUglify.rewriteStyles($).html(); | ||
assert.equal(results, '<style>@media{.media{background: red}}</style>'); | ||
assert.equal(results, '<style>@media{.xz{background: red}}</style>'); | ||
}); | ||
}); | ||
describe('#pointerizeClass', function() { | ||
var $element; | ||
beforeEach(function() { | ||
var html = '<p class="one two"></p>'; | ||
var $ = cheerio.load(html); | ||
$element = $('p').first(); | ||
}); | ||
it('works with empty lookups', function() { | ||
var lookups = {}; | ||
htmlUglify.pointerizeClass($element, lookups); | ||
assert.deepEqual(lookups, { class: { one: 'xz', two: 'wk' } }); | ||
}); | ||
it('works with single lookup', function() { | ||
var lookups = { class: { one: 'ab' } }; | ||
htmlUglify.pointerizeClass($element, lookups); | ||
assert.deepEqual(lookups, { class: { one: 'ab', two: 'wk' } }); | ||
}); | ||
it('works with whitelist', function() { | ||
var lookups = {}; | ||
htmlUglify.whitelist = [ '.two' ]; | ||
htmlUglify.pointerizeClass($element, lookups); | ||
assert.deepEqual(lookups, { class: { one: 'xz' } }); | ||
}); | ||
}); | ||
describe('#pointerizeIdAndFor', function() { | ||
var $element; | ||
beforeEach(function() { | ||
var html = '<p id="one"></p>'; | ||
var $ = cheerio.load(html); | ||
$element = $('p').first(); | ||
}); | ||
it('works with empty lookups', function() { | ||
var lookups = {}; | ||
htmlUglify.pointerizeIdAndFor('id', $element, lookups); | ||
assert.deepEqual(lookups, { id: { one: 'xz' } }); | ||
}); | ||
it('works with existing lookup', function() { | ||
var lookups = { class: { one: 'ab' } }; | ||
htmlUglify.pointerizeClass($element, lookups); | ||
assert.deepEqual(lookups, { class: { one: 'ab' } }); | ||
}); | ||
it('works with whitelist', function() { | ||
var lookups = {}; | ||
htmlUglify.whitelist = [ '#one' ]; | ||
htmlUglify.pointerizeClass($element, lookups); | ||
assert.deepEqual(lookups, {}); | ||
}); | ||
}); | ||
describe('#rewriteElements', function() { | ||
@@ -241,6 +400,18 @@ it('rewrites an id', function() { | ||
describe('#insertLookup', function() { | ||
var lookups; | ||
beforeEach(function() { | ||
lookups = {}; | ||
}); | ||
it('updates lookups', function() { | ||
htmlUglify.insertLookup('class', 'testClass', 'xz', lookups); | ||
assert.equal(lookups['class'].testClass, 'xz'); | ||
}); | ||
}); | ||
describe('#process', function() { | ||
it('uglifies style and html', function() { | ||
var html = htmlUglify.process("<style>.demo_class#andID{color: red}</style><div class='demo_class' id='andID'>Welcome to HTML Uglify</div>"); | ||
assert.equal(html, '<style>.wk#xz{color: red}</style><div class="wk" id="xz">Welcome to HTML Uglify</div>'); | ||
var html = htmlUglify.process("<style>.test#other{}</style><p class='test' id='other'></p>"); | ||
assert.equal(html, '<style>.xz#wk{}</style><p class="xz" id="wk"></p>'); | ||
}); | ||
@@ -250,3 +421,3 @@ it('uglifies differently with a different salt', function() { | ||
var html = htmlUglify.process("<style>.demo_class#andID{color: red}</style><div class='demo_class' id='andID'>Welcome to HTML Uglify</div>"); | ||
assert.equal(html, '<style>.nx#vy{color: red}</style><div class="nx" id="vy">Welcome to HTML Uglify</div>'); | ||
assert.equal(html, '<style>.vy#nx{color: red}</style><div class="vy" id="nx">Welcome to HTML Uglify</div>'); | ||
}); | ||
@@ -275,4 +446,97 @@ it('uglifies media query with no name', function() { | ||
}); | ||
it('uglifies class attribute selectors', function() { | ||
var html = htmlUglify.process('<style>body[yahoo] *[class*=paddingreset] {}</style><div class="paddingreset1">paddingreset1</div>'); | ||
assert.equal(html, '<style>body[yahoo] *[class*=xz] {}</style><div class="xz1">paddingreset1</div>'); | ||
}); | ||
it('uglifies id attribute selectors', function() { | ||
var html = htmlUglify.process('<style>body[yahoo] *[id*=paddingreset] { padding:0 !important; }</style><div id="paddingreset1">paddingreset1</div>'); | ||
assert.equal(html, '<style>body[yahoo] *[id*=xz] { padding:0 !important; }</style><div id="xz1">paddingreset1</div>'); | ||
}); | ||
it('uglifies for attribute selectors', function() { | ||
var html = htmlUglify.process('<style>body[yahoo] *[id*=paddingreset] { padding:0 !important; }</style><div for="paddingreset1">paddingreset1</div>'); | ||
assert.equal(html, '<style>body[yahoo] *[id*=xz] { padding:0 !important; }</style><div for="xz1">paddingreset1</div>'); | ||
}); | ||
it('uglifies attribute selectors correctly towards the end of a stylesheet', function() { | ||
var html = htmlUglify.process("<style>.test{} .alphatest{} *[class*=test]{}</style><p class='alphatest'></p>"); | ||
assert.equal(html, '<style>.xz{} .alphaxz{} *[class*=xz]{}</style><p class="alphaxz"></p>'); | ||
}); | ||
it('uglifies attribute selectors with spaced classes', function() { | ||
var html = htmlUglify.process("<style>.test{} .alphatest{} *[class*=test]{}</style><p class='alphatest beta'></p>"); | ||
assert.equal(html, '<style>.xz{} .alphaxz{} *[class*=xz]{}</style><p class="alphaxz en"></p>'); | ||
}); | ||
}); | ||
describe('attribute selectors', function() { | ||
describe('equal selector', function() { | ||
it('uglifies', function() { | ||
var html = htmlUglify.process('<style>*[class=test] {}</style><div class="test"></div>'); | ||
assert.equal(html, '<style>*[class=xz] {}</style><div class="xz"></div>'); | ||
html = htmlUglify.process('<style>*[id=test] {}</style><div id="test"></div>'); | ||
assert.equal(html, '<style>*[id=xz] {}</style><div id="xz"></div>'); | ||
html = htmlUglify.process('<style>*[id=test] {}</style><div for="test"></div>'); | ||
assert.equal(html, '<style>*[id=xz] {}</style><div for="xz"></div>'); | ||
}); | ||
}); | ||
describe('anywhere selector', function() { | ||
it('uglifies in the middle of a string', function() { | ||
var html = htmlUglify.process('<style>*[class*=test] {}</style><div class="ZZtestZZ"></div>'); | ||
assert.equal(html, '<style>*[class*=xz] {}</style><div class="ZZxzZZ"></div>'); | ||
html = htmlUglify.process('<style>*[id*=test] {}</style><div id="ZZtestZZ"></div>'); | ||
assert.equal(html, '<style>*[id*=xz] {}</style><div id="ZZxzZZ"></div>'); | ||
html = htmlUglify.process('<style>*[id*=test] {}</style><div for="ZZtestZZ"></div>'); | ||
assert.equal(html, '<style>*[id*=xz] {}</style><div for="ZZxzZZ"></div>'); | ||
}); | ||
it('uglifies at the start of a string', function() { | ||
var html = htmlUglify.process('<style>*[class*=test] {}</style><div class="testZZ"></div>'); | ||
assert.equal(html, '<style>*[class*=xz] {}</style><div class="xzZZ"></div>'); | ||
html = htmlUglify.process('<style>*[id*=test] {}</style><div id="testZZ"></div>'); | ||
assert.equal(html, '<style>*[id*=xz] {}</style><div id="xzZZ"></div>'); | ||
html = htmlUglify.process('<style>*[id*=test] {}</style><div for="testZZ"></div>'); | ||
assert.equal(html, '<style>*[id*=xz] {}</style><div for="xzZZ"></div>'); | ||
}); | ||
it('uglifies at the end of a string', function() { | ||
var html = htmlUglify.process('<style>*[class*=test] {}</style><div class="ZZtest"></div>'); | ||
assert.equal(html, '<style>*[class*=xz] {}</style><div class="ZZxz"></div>'); | ||
html = htmlUglify.process('<style>*[id*=test] {}</style><div id="ZZtest"></div>'); | ||
assert.equal(html, '<style>*[id*=xz] {}</style><div id="ZZxz"></div>'); | ||
html = htmlUglify.process('<style>*[id*=test] {}</style><div for="ZZtest"></div>'); | ||
assert.equal(html, '<style>*[id*=xz] {}</style><div for="ZZxz"></div>'); | ||
}); | ||
}); | ||
describe('begins with selector', function() { | ||
it('uglifies at the start of a string', function() { | ||
var html = htmlUglify.process('<style>*[class^=test] {}</style><div class="testZZ"></div>'); | ||
assert.equal(html, '<style>*[class^=xz] {}</style><div class="xzZZ"></div>'); | ||
html = htmlUglify.process('<style>*[id^=test] {}</style><div id="testZZ"></div>'); | ||
assert.equal(html, '<style>*[id^=xz] {}</style><div id="xzZZ"></div>'); | ||
html = htmlUglify.process('<style>*[id^=test] {}</style><div for="testZZ"></div>'); | ||
assert.equal(html, '<style>*[id^=xz] {}</style><div for="xzZZ"></div>'); | ||
}); | ||
}); | ||
describe('ends with selector', function() { | ||
it('uglifies at the end of a string', function() { | ||
var html = htmlUglify.process('<style>*[class$=test] {}</style><div class="ZZtest"></div>'); | ||
assert.equal(html, '<style>*[class$=xz] {}</style><div class="ZZxz"></div>'); | ||
html = htmlUglify.process('<style>*[id$=test] {}</style><div id="ZZtest"></div>'); | ||
assert.equal(html, '<style>*[id$=xz] {}</style><div id="ZZxz"></div>'); | ||
html = htmlUglify.process('<style>*[id$=test] {}</style><div for="ZZtest"></div>'); | ||
assert.equal(html, '<style>*[id$=xz] {}</style><div for="ZZxz"></div>'); | ||
}); | ||
}); | ||
}); | ||
}); | ||
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
44730
13
681
3
1