Skip to content

Commit

Permalink
Merge pull request #846 from danwaz/feature/issue-813-no-url-protocol…
Browse files Browse the repository at this point in the history
…-fix

Updates no-url-protocols rule and adds additional no-domains rule
  • Loading branch information
DanPurdy authored Aug 26, 2016
2 parents c3a0260 + 21f836e commit 01eb696
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 11 deletions.
37 changes: 37 additions & 0 deletions docs/rules/no-url-domains.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# No Url Domains

Rule `no-url-domains` will enforce that domains are not used within urls.

## Examples

When enabled, the following are allowed:

```scss
.foo {
background-image: url('/img/bar.png');
}

.foo {
background-image: url('img/bar.png');
}

.foo {
background-image: url('bar.png');
}
```

When enabled, the following are disallowed:

```scss
.foo {
background-image: url('https://foo.com/img/bar.png');
}

.foo {
background-image: url('http://foo.com/img/bar.png');
}

.foo {
background-image: url('//foo.com/img/bar.png');
}
```
44 changes: 42 additions & 2 deletions docs/rules/no-url-protocols.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@

Rule `no-url-protocols` will enforce that protocols and domains are not used within urls.

## Options

* `allow-protocol-relative-urls`: `true`/`false` (defaults to `false`)
> This option is scheduled to be deprecated in favour of the [no-url-domains](https://github.com/sasstools/sass-lint/blob/develop/docs/rules/no-url-domains.md) rule in sass-lint 2.0.
## Examples

When enabled, the following are allowed:
### `allow-protocol-relative-urls`


When `allow-protocol-relative-urls: false`, the following are allowed:

```scss
.foo {
Expand All @@ -20,7 +28,7 @@ When enabled, the following are allowed:
}
```

When enabled, the following are disallowed:
When `allow-protocol-relative-urls: false`, the following are disallowed:

```scss
.foo {
Expand All @@ -35,3 +43,35 @@ When enabled, the following are disallowed:
background-image: url('//foo.com/img/bar.png');
}
```

When `allow-protocol-relative-urls: true`, the following are allowed:

```scss
.foo {
background-image: url('//foo.com/img/bar.png');
}

.foo {
background-image: url('/img/bar.png');
}

.foo {
background-image: url('img/bar.png');
}

.foo {
background-image: url('bar.png');
}
```

When `allow-protocol-relative-urls: true`, the following are disallowed:

```scss
.foo {
background-image: url('https://foo.com/img/bar.png');
}

.foo {
background-image: url('http://foo.com/img/bar.png');
}
```
1 change: 1 addition & 0 deletions lib/config/sass-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ rules:
no-trailing-zero: 1
no-transition-all: 1
no-universal-selectors: 0
no-url-domains: 1
no-url-protocols: 1
no-vendor-prefixes: 1
no-warn: 1
Expand Down
33 changes: 33 additions & 0 deletions lib/rules/no-url-domains.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';

var helpers = require('../helpers'),
url = require('url');

module.exports = {
'name': 'no-url-domains',
'defaults': {},
'detect': function (ast, parser) {
var result = [];

ast.traverseByType('uri', function (uri) {
uri.traverse(function (item) {
if (item.is('string')) {
var stripped = helpers.stripQuotes(item.content),
parsedUrl = url.parse(stripped, false, true);

if (parsedUrl.host && parsedUrl.protocol !== 'data:') {
result = helpers.addUnique(result, {
'ruleId': parser.rule.name,
'severity': parser.severity,
'line': item.end.line,
'column': item.end.column,
'message': 'Domains in URLs are disallowed'
});
}
}
});
});

return result;
}
};
22 changes: 13 additions & 9 deletions lib/rules/no-url-protocols.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,34 @@

var helpers = require('../helpers');

var isUrlRegex = /^(https?:)?\/\//;

var stripQuotes = function (str) {
return str.substring(1, str.length - 1);
};
var isUrlRegex = /^(https?:)?\/\//,
protocolRelativeRegex = /^(https?:)\/\//;

module.exports = {
'name': 'no-url-protocols',
'defaults': {},
'defaults': {
'allow-protocol-relative-urls': false
},
'detect': function (ast, parser) {
var result = [];

ast.traverseByType('uri', function (uri) {
uri.traverse(function (item) {
if (item.is('string')) {
var stripped = stripQuotes(item.content);
var stripped = helpers.stripQuotes(item.content),
regexSelector = !parser.options['allow-protocol-relative-urls'] ?
isUrlRegex : protocolRelativeRegex,
message = !parser.options['allow-protocol-relative-urls'] ?
'Protocols and domains in URLs are disallowed' :
'Protocols in URLS are disallowed';

if (stripped.match(isUrlRegex)) {
if (stripped.match(regexSelector)) {
result = helpers.addUnique(result, {
'ruleId': parser.rule.name,
'severity': parser.severity,
'line': item.end.line,
'column': item.end.column,
'message': 'Protocols and domains in URLs are disallowed'
'message': message
});
}
}
Expand Down
35 changes: 35 additions & 0 deletions tests/rules/no-url-domains.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict';

var lint = require('./_lint');

//////////////////////////////
// SCSS syntax tests
//////////////////////////////
describe('no url domains - scss', function () {
var file = lint.file('no-url-domains.scss');

it('enforce', function (done) {
lint.test(file, {
'no-url-domains': 1
}, function (data) {
lint.assert.equal(3, data.warningCount);
done();
});
});
});

//////////////////////////////
// Sass syntax tests
//////////////////////////////
describe('no url domains - sass', function () {
var file = lint.file('no-url-domains.sass');

it('enforce', function (done) {
lint.test(file, {
'no-url-domains': 1
}, function (data) {
lint.assert.equal(3, data.warningCount);
done();
});
});
});
29 changes: 29 additions & 0 deletions tests/rules/no-url-protocols.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,23 @@ describe('no url protocols - scss', function () {
done();
});
});

it('[allow-protocol-relative-urls: true]', function (done) {
lint.test(file, {
'no-url-protocols': [
1,
{
'allow-protocol-relative-urls': true
}
]
}, function (data) {
lint.assert.equal(2, data.warningCount);
done();
});
});
});


//////////////////////////////
// Sass syntax tests
//////////////////////////////
Expand All @@ -32,4 +47,18 @@ describe('no url protocols - sass', function () {
done();
});
});

it('[allow-protocol-relative-urls: true]', function (done) {
lint.test(file, {
'no-url-protocols': [
1,
{
'allow-protocol-relative-urls': true
}
]
}, function (data) {
lint.assert.equal(2, data.warningCount);
done();
});
});
});
25 changes: 25 additions & 0 deletions tests/sass/no-url-domains.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.foo
background-image: url('https://foo.com/img/bar.png')


.foo
background-image: url('http://foo.com/img/bar.png')


.foo
background-image: url('//foo.com/img/bar.png')


.foo
background-image: url('/img/bar.png')


.foo
background-image: url('img/bar.png')


.foo
background-image: url('bar.png')

.foo
background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7')
27 changes: 27 additions & 0 deletions tests/sass/no-url-domains.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.foo {
background-image: url('https://foo.com/img/bar.png');
}

.foo {
background-image: url('http://foo.com/img/bar.png');
}

.foo {
background-image: url('//foo.com/img/bar.png');
}

.foo {
background-image: url('/img/bar.png');
}

.foo {
background-image: url('img/bar.png');
}

.foo {
background-image: url('bar.png');
}

.foo {
background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
}

0 comments on commit 01eb696

Please sign in to comment.