Socket
Socket
Sign inDemoInstall

ember-template-lint

Package Overview
Dependencies
Maintainers
1
Versions
215
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ember-template-lint - npm Package Compare versions

Comparing version 0.5.0-alpha.1 to 0.5.0

lib/index.js

62

CHANGELOG.md
Changelog
=========
## v0.3.5
## v0.5.0
- Update the `bare-strings` rule to allow the following configuration:
* boolean -- `true` for enabled / `false` for disabled
* array -- an array of whitelisted strings
* object -- An object with the following keys:
* `whitelist` -- An array of whitelisted strings
* `globalAttributes` -- An array of attributes to check on every element.
* `elementAttributes` -- An object whose keys are tag names and value is an array of attributes to check for that tag name.
- Change default `.template-lintrc.js` file value for `bare-strings` to be `true`, which defaults the configuration to:
```js
{
whitelist: ['(', ')', ',', '.', '&', '+', '-', '=', '*', '/', '#', '%', '!', '?', ':', '[', ']', '{', '}'],
globalAttributes: [ 'title' ],
elementAttributes: { input: [ 'placeholder' ], img: [ 'alt' ]}
};
```
- Fix bug with `bare-strings` where an allowed whitelisted string would only be allowed once in a given string. i.e `&&` would have failed, even though `&` was a whitelisted string.
## v0.3.4
- Add support for TextNode/CommentNode location information. Now the `bare-strings` / `html-comments` rules include line and column info.
- Add `nested-interactive` rule. Usage of nested interactive content can lead to UX problems, accessibility problems, bugs and in some
cases to DOM errors. You should not put interactive content elements nested inside other interactive content elements.
## v0.3.3
- Fix issue with per-template rule configuration.
## v0.3.2
- Fix issue with `block-indentation` rule when a given block starts on the same line as a previous item. i.e.:
```hbs
{{! good }}
{{#each foo as |bar|}}
<span>{{bar.name}}:</span><span>{{bar.title}}</span>
{{/each}}
```
## v0.3.1
- Add `html-comments` rule which forbids the usage of HTML comments (other than `<!-- template-lint bare-strings=false -->` style control comments).
## v0.3.0
- Change default configuration so that no plugins are enabled (warns when `.template-lintrc.js` is not found).
## v0.2.13
- Add better default whitelist for `bare-strings` rule.
## v0.2.12
- Add blueprint that generate `.template-lintrc.js`.
- Deprecate using ember-cli-template-lint without a `.template-lintrc.js`.
- Initial migration of plugins from ember-cli-template-lint.
- Implement new node API for the Linter.
- Implement new result objects.
'use strict';
module.exports = function(addonContext, name) {
module.exports = function(options) {
var log = options.log;
var config = options.config;
var ruleName = options.name;
function BasePlugin(options) {

@@ -11,5 +15,5 @@ this.options = options;

this.config = this.parseConfig(
addonContext.loadConfig()[name]
);
this.ruleName = ruleName;
this.config = this.parseConfig(config);
this._log = log;
}

@@ -76,3 +80,3 @@

// handle <!-- template-lint block-indentation=false -->
if (key === name && value === 'false') {
if (key === ruleName && value === 'false') {
this.config = false;

@@ -87,4 +91,7 @@ }

BasePlugin.prototype.log = function(message) {
addonContext.logLintingError(name, this.options.moduleName, message);
BasePlugin.prototype.log = function(result) {
result.moduleId = this.options.moduleName;
result.rule = this.ruleName;
this._log(result);
};

@@ -91,0 +98,0 @@

@@ -25,3 +25,2 @@ 'use strict';

var calculateLocationDisplay = require('../helpers/calculate-location-display');
var buildPlugin = require('./base');

@@ -122,3 +121,3 @@ var astInfo = require('../helpers/ast-node-info');

var attributeValueNode = attribute.value;
var additionalDescription = 'in `' + attributeType + '` attribute ';
var additionalDescription = ' in `' + attributeType + '` attribute';
var isGlobalAttribute = this.config.globalAttributes.indexOf(attributeType) > -1;

@@ -153,6 +152,8 @@ var isElementAttribute = this.config.elementAttributes[tag] && this.config.elementAttributes[tag].indexOf(attributeType) > -1;

if (bareStringText) {
var locationDisplay = calculateLocationDisplay(this.options.moduleName, loc && loc.start);
var warning = 'Non-translated string used ' + additionalDescription + locationDisplay + ': `' + bareStringText + '`.';
this.log(warning);
this.log({
message: 'Non-translated string used' + additionalDescription,
line: loc.start.line,
column: loc.start.column,
source: bareStringText
});
}

@@ -159,0 +160,0 @@ };

@@ -51,3 +51,2 @@ 'use strict';

var calculateLocationDisplay = require('../helpers/calculate-location-display');
var buildPlugin = require('./base');

@@ -152,4 +151,4 @@ var VOID_TAGS = { area: true,

if(correctedEndColumn !== startColumn) {
var startLocation = calculateLocationDisplay(this.options.moduleName, node.loc && node.loc.start);
var endLocation = calculateLocationDisplay(this.options.moduleName, node.loc && node.loc.end);
var startLocation = 'L' + node.loc.start.line + ':C' + node.loc.start.column;
var endLocation = 'L' + node.loc.end.line + ':C' + node.loc.end.column;

@@ -159,3 +158,9 @@ var warning = 'Incorrect indentation for `' + displayName + '` beginning at ' + startLocation +

'was found at ' + correctedEndColumn + '.';
this.log(warning);
this.log({
message: warning,
line: node.loc.end.line,
column: node.loc.end.column,
source: this.sourceForNode(node)
});
}

@@ -252,4 +257,3 @@ };

var startLocation = calculateLocationDisplay(this.options.moduleName, child.loc && child.loc.start);
var startLocation = 'L' + child.loc.start.line + ':C' + child.loc.start.column;
var warning = 'Incorrect indentation for `' + display + '` beginning at ' + startLocation +

@@ -259,3 +263,8 @@ '. Expected `' + display + '` to be at an indentation of ' + expectedStartColumn + ' but ' +

this.log(warning);
this.log({
message: warning,
line: child.loc && child.loc.start.line,
column: child.loc && child.loc.start.column,
source: this.sourceForNode(node)
});
}

@@ -262,0 +271,0 @@ }

'use strict';
var calculateLocationDisplay = require('../helpers/calculate-location-display');
var AstNodeInfo = require('../helpers/ast-node-info');

@@ -32,5 +31,8 @@ var buildPlugin = require('./base');

LogHtmlComments.prototype.process = function(node) {
var location = calculateLocationDisplay(this.options.moduleName, node.loc && node.loc.start);
this.log('Html comment detected `<!--' + node.value + '-->` at ' + location +
'. Use Handlebars comment instead `{{!--' + node.value +'--}}`');
this.log({
message: 'HTML comment detected',
line: node.loc && node.loc.start.line,
column: node.loc && node.loc.start.column,
source: '<!--' + node.value + '-->'
});
};

@@ -37,0 +39,0 @@

@@ -19,3 +19,2 @@ 'use strict';

var calculateLocationDisplay = require('../helpers/calculate-location-display');
var buildPlugin = require('./base');

@@ -209,4 +208,3 @@

return 'Don\'t use ' + childNodeError + ' inside ' + parentNodeError + ' ' +
calculateLocationDisplay(this.options.moduleName, node.loc.start);
return 'Do not use ' + childNodeError + ' inside ' + parentNodeError;
};

@@ -217,3 +215,9 @@

if (this.isInteractiveElement(node, whitelistTests)) {
this.log(this.getLogMessage(node, parentInteractiveNode));
this.log({
message: this.getLogMessage(node, parentInteractiveNode),
line: node.loc && node.loc.start.line,
column: node.loc && node.loc.start.column,
source: this.sourceForNode(node)
});
return;

@@ -220,0 +224,0 @@ }

'use strict';
var calculateLocationDisplay = require('../helpers/calculate-location-display');
var buildPlugin = require('./base');

@@ -31,5 +30,8 @@

LogTripleCurlies.prototype.process = function(node) {
var location = calculateLocationDisplay(this.options.moduleName, node.loc && node.loc.start);
this.log('Usage of triple curly brackets is unsafe `{{{' + node.path.original + '}}}` at ' + location);
this.log({
message: 'Usage of triple curly brackets is unsafe',
line: node.loc && node.loc.start.line,
column: node.loc && node.loc.start.column,
source: '{{{' + node.path.original + '}}}'
});
};

@@ -36,0 +38,0 @@

'use strict';
/*eslint no-console: [0] */
var path = require('path');

@@ -7,4 +9,4 @@ var existsSync = require('exists-sync');

function buildDefaultConfig(ui) {
ui.log(chalk.yellow('\nember-cli-template-lint requires a configuration file to enable rules. Please generate one with `ember generate ember-cli-template-lint`.'));
function buildDefaultConfig(console) {
console.log(chalk.yellow('\nember-cli-template-lint requires a configuration file to enable rules. Please generate one with `ember generate ember-cli-template-lint`.'));

@@ -19,3 +21,3 @@ return {};

if(existsSync(configPath + '.js') || existsSync(configPath + '.json')) {
if(existsSync(configPath) || existsSync(configPath + '.js') || existsSync(configPath + '.json')) {
return require(configPath);

@@ -22,0 +24,0 @@ } else {

{
"name": "ember-template-lint",
"version": "0.5.0-alpha.1",
"version": "0.5.0",
"description": "Lint your templates.",

@@ -19,3 +19,5 @@ "scripts": {

"devDependencies": {
"assert-diff": "^1.0.1",
"eslint-plugin-node": "^1.0.0",
"espower-loader": "^1.0.0",
"glob": "^7.0.0",

@@ -26,3 +28,5 @@ "loader.js": "^4.0.1",

"mocha-only-detector": "^0.1.0",
"rimraf": "^2.5.2"
"power-assert": "^1.3.1",
"rimraf": "^2.5.2",
"testem": "^1.6.0"
},

@@ -29,0 +33,0 @@ "keywords": [],

# ember-cli-template-lint
[![Build Status](https://travis-ci.org/rwjblue/ember-cli-template-lint.svg?branch=master)](https://travis-ci.org/rwjblue/ember-cli-template-lint)
[![Build Status](https://travis-ci.org/rwjblue/ember-template-lint.svg?branch=master)](https://travis-ci.org/rwjblue/ember-template-lint)
ember-cli-template-lint will lint your templates and add a test for each asserting
that all style rules have been satisfied.
ember-template-lint will lint your template and return error results. This is commonly
used through ember-cli-template-lint which adds failing lint tests for consuming ember-cli
applications.

@@ -16,15 +17,13 @@ For example, given the rule `bare-strings` is enabled, this template would be

Thus a the test `TemplateLint: app/components/my-thing/template.hbs` would
fail with the assertion "A bare string was found (0:5)".
When ran throught the linters `verify` method we would have a single result indicating that
the `bare-strings` rule found an error.
## Install
To install ember-cli-template-lint
To install ember-template-lint
```
ember install ember-cli-template-lint
npm install --save-dev ember-template-lint
```
__Ember CLI >= 2.4.2 is required for linting templates__
## Configuration

@@ -205,19 +204,5 @@

* `npm install`
* `bower install`
### Running
* `ember server`
* Visit your app at http://localhost:4200.
### Running Tests
* `npm run test-node`
* `ember test`
* `ember test --server`
### Building
* `ember build`
For more information on using ember-cli, visit [http://www.ember-cli.com/](http://www.ember-cli.com/).
* `npm test`
'use strict';
var assert = require('assert');
var _compile = require('htmlbars').compile;
var plugins = require('../../ext/plugins');
var assert = require('power-assert');
var assertDiff = require('assert-diff');
var Linter = require('../../lib/index');

@@ -13,62 +13,56 @@ module.exports = function(options) {

var addonContext, messages, config;
var linter, config;
function compile(template) {
_compile(template, {
rawSource: template,
moduleName: 'layout.hbs',
plugins: {
ast: [
plugins[options.name](addonContext)
]
}
});
function verify(template) {
linter.config[options.name] = config;
return linter.verify({ source: template, moduleId: 'layout.hbs' });
}
beforeEach(function() {
messages = [];
config = {};
config[options.name] = options.config;
var fullConfig = {};
fullConfig[options.name] = config = options.config;
addonContext = {
logLintingError: function(pluginName, moduleName, message) {
messages.push(message);
},
loadConfig: function() {
return config;
}
};
linter = new Linter({
config: fullConfig
});
});
options.bad.forEach(function(badItem) {
var testMethod = badItem.focus ? it.only : it;
var expectedMessages = badItem.messages || [badItem.message];
var testMethod;
if (badItem.focus) {
testMethod = it.only;
} else {
testMethod = it;
}
testMethod('logs a message in the console when given `' + badItem.template + '`', function() {
var expectedResults = badItem.results || [badItem.result];
if (badItem.config) {
config[options.name] = badItem.config;
config = badItem.config;
}
compile(badItem.template);
var actual = verify(badItem.template);
assert.deepEqual(messages, expectedMessages);
assertDiff.deepEqual(actual, expectedResults);
});
it('passes with `' + badItem.template + '` when rule is disabled', function() {
config[options.name] = false;
compile(badItem.template);
config = false;
var actual = verify(badItem.template);
assert.deepEqual(messages, []);
assert.deepEqual(actual, []);
});
it('passes with `' + badItem.template + '` when disabled via inline comment - single rule', function() {
compile(DISABLE_ONE + '\n' + badItem.template);
var actual = verify(DISABLE_ONE + '\n' + badItem.template);
assert.deepEqual(messages, []);
assert.deepEqual(actual, []);
});
it('passes with `' + badItem.template + '` when disabled via inline comment - all rules', function() {
compile(DISABLE_ALL + '\n' + badItem.template);
var actual = verify(DISABLE_ALL + '\n' + badItem.template);
assert.deepEqual(messages, []);
assert.deepEqual(actual, []);
});

@@ -82,13 +76,14 @@ });

testMethod('passes when given `' + template + '`', function() {
var actual;
if (typeof item === 'string') {
compile(item);
actual = verify(item);
} else {
if (item.config !== undefined) {
config[options.name] = item.config;
config = item.config;
}
compile(template);
actual = verify(template);
}
assert.deepEqual(messages, []);
assert.deepEqual(actual, []);
});

@@ -95,0 +90,0 @@ });

'use strict';
var assert = require('assert');
var assert = require('power-assert');
var _compile = require('htmlbars').compile;

@@ -9,6 +9,12 @@ var buildPlugin = require('./../../ext/plugins/base');

describe('base plugin tests', function() {
var addonContext, messages, config;
var messages, config;
function plugin(addonContext) {
var FakePlugin = buildPlugin(addonContext, 'fake');
function plugin() {
var FakePlugin = buildPlugin({
log: function(result) {
messages.push(result.source);
},
name: 'fake',
config: config
});

@@ -20,3 +26,8 @@ FakePlugin.prototype.detect = function(node) {

FakePlugin.prototype.process = function(node) {
this.log(this.sourceForNode(node));
this.log({
message: 'Node source',
line: node.loc && node.loc.start.line,
column: node.loc && node.loc.start.column,
source: this.sourceForNode(node)
});
};

@@ -33,3 +44,3 @@

ast: [
plugin(addonContext)
plugin()
]

@@ -43,11 +54,2 @@ }

config = {};
addonContext = {
logLintingError: function(pluginName, moduleName, message) {
messages.push(message);
},
loadConfig: function() {
return config;
}
};
});

@@ -54,0 +56,0 @@

'use strict';
var assert = require('assert');
var assert = require('power-assert');
var _compile = require('htmlbars').compile;

@@ -5,0 +5,0 @@

@@ -67,8 +67,38 @@ 'use strict';

bad: [
{ template: '\n howdy', message: 'Non-translated string used (\'layout.hbs\'@ L1:C0): `\n howdy`.' },
{ template: '<div>\n 1234\n</div>', message: 'Non-translated string used (\'layout.hbs\'@ L1:C5): `\n 1234\n`.' },
{
template: '\n howdy',
result: {
rule: 'bare-strings',
moduleId: 'layout.hbs',
message: 'Non-translated string used',
line: 1,
column: 0,
source: '\n howdy'
}
},
{
template: '<div>\n 1234\n</div>',
result: {
rule: 'bare-strings',
moduleId: 'layout.hbs',
message: 'Non-translated string used',
line: 1,
column: 5,
source: '\n 1234\n'
}
},
{
template: '<a title="hahaha trolol"></a>',
message: 'Non-translated string used in `title` attribute (\'layout.hbs\'@ L1:C4): `hahaha trolol`.'
result: {
rule: 'bare-strings',
moduleId: 'layout.hbs',
message: 'Non-translated string used in `title` attribute',
line: 1,
column: 4,
source: 'hahaha trolol'
}
},

@@ -78,3 +108,11 @@

template: '<input placeholder="trolol">',
message: 'Non-translated string used in `placeholder` attribute (\'layout.hbs\'@ L1:C8): `trolol`.'
result: {
rule: 'bare-strings',
moduleId: 'layout.hbs',
message: 'Non-translated string used in `placeholder` attribute',
line: 1,
column: 8,
source: 'trolol'
}
},

@@ -85,3 +123,11 @@

template: '<div data-foo="derpy"></div>',
message: 'Non-translated string used in `data-foo` attribute (\'layout.hbs\'@ L1:C6): `derpy`.'
result: {
rule: 'bare-strings',
moduleId: 'layout.hbs',
message: 'Non-translated string used in `data-foo` attribute',
line: 1,
column: 6,
source: 'derpy'
}
},

@@ -92,3 +138,11 @@

template: '<img data-alt="some alternate here">',
message: 'Non-translated string used in `data-alt` attribute (\'layout.hbs\'@ L1:C6): `some alternate here`.'
result: {
rule: 'bare-strings',
moduleId: 'layout.hbs',
message: 'Non-translated string used in `data-alt` attribute',
line: 1,
column: 6,
source: 'some alternate here'
}
},

@@ -99,5 +153,18 @@

template: '<div>Bady\n <input placeholder="trolol">\n</div>',
messages: [
'Non-translated string used (\'layout.hbs\'@ L1:C5): `Bady\n `.',
'Non-translated string used in `placeholder` attribute (\'layout.hbs\'@ L2:C10): `trolol`.'
results: [
{
rule: 'bare-strings',
moduleId: 'layout.hbs',
message: 'Non-translated string used',
line: 1,
column: 5,
source: 'Bady\n '
}, {
rule: 'bare-strings',
moduleId: 'layout.hbs',
message: 'Non-translated string used in `placeholder` attribute',
line: 2,
column: 10,
source: 'trolol'
}
]

@@ -104,0 +171,0 @@ }

@@ -94,8 +94,23 @@ 'use strict';

message: 'Incorrect indentation for `each` beginning at (\'layout.hbs\'@ L2:C2). Expected `{{/each}}` ending at (\'layout.hbs\'@ L3:C17) to be at an indentation of 2 but was found at 8.'
result: {
rule: 'block-indentation',
message: 'Incorrect indentation for `each` beginning at L2:C2. Expected `{{/each}}` ending at L3:C17 to be at an indentation of 2 but was found at 8.',
moduleId: 'layout.hbs',
source: '{{#each cats as |dog|}}\n {{/each}}',
line: 3,
column: 17
}
},
{
template: '<div>\n <p>Stuff goes here</p></div>',
message: 'Incorrect indentation for `div` beginning at (\'layout.hbs\'@ L1:C0). Expected `</div>` ending at (\'layout.hbs\'@ L2:C30) to be at an indentation of 0 but was found at 24.'
result: {
rule: 'block-indentation',
message: 'Incorrect indentation for `div` beginning at L1:C0. Expected `</div>` ending at L2:C30 to be at an indentation of 0 but was found at 24.',
moduleId: 'layout.hbs',
source: '<div>\n <p>Stuff goes here</p></div>',
line: 2,
column: 30
}
},

@@ -105,3 +120,10 @@ {

message: 'Incorrect indentation for `<p>` beginning at (\'layout.hbs\'@ L2:C0). Expected `<p>` to be at an indentation of 2 but was found at 0.'
result: {
rule: 'block-indentation',
message: 'Incorrect indentation for `<p>` beginning at L2:C0. Expected `<p>` to be at an indentation of 2 but was found at 0.',
moduleId: 'layout.hbs',
source: '<div>\n<p>Stuff goes here</p>\n</div>',
line: 2,
column: 0
}
},

@@ -111,3 +133,10 @@ {

message: 'Incorrect indentation for `<p>` beginning at (\'layout.hbs\'@ L2:C0). Expected `<p>` to be at an indentation of 2 but was found at 0.'
result: {
rule: 'block-indentation',
message: 'Incorrect indentation for `<p>` beginning at L2:C0. Expected `<p>` to be at an indentation of 2 but was found at 0.',
moduleId: 'layout.hbs',
source: '{{#if}}\n<p>Stuff goes here</p>\n{{/if}}',
line: 2,
column: 0
}
},

@@ -122,3 +151,10 @@ {

message: 'Incorrect indentation for `if` beginning at (\'layout.hbs\'@ L3:C2). Expected `{{/if}}` ending at (\'layout.hbs\'@ L5:C11) to be at an indentation of 2 but was found at 4.'
result: {
rule: 'block-indentation',
message: 'Incorrect indentation for `if` beginning at L3:C2. Expected `{{/if}}` ending at L5:C11 to be at an indentation of 2 but was found at 4.',
moduleId: 'layout.hbs',
source: '{{#if something}}\n Good night\n {{/if}}',
line: 5,
column: 11
}
},

@@ -133,3 +169,10 @@ {

message: 'Incorrect indentation for `<p>` beginning at (\'layout.hbs\'@ L2:C2). Expected `<p>` to be at an indentation of 4 but was found at 2.'
result: {
rule: 'block-indentation',
message: 'Incorrect indentation for `<p>` beginning at L2:C2. Expected `<p>` to be at an indentation of 4 but was found at 2.',
moduleId: 'layout.hbs',
source: '<div>\n <p>Hi!</p>\n</div>',
line: 2,
column: 2
}
},

@@ -142,3 +185,10 @@ {

message: 'Incorrect indentation for `{{bar}}` beginning at (\'layout.hbs\'@ L3:C0). Expected `{{bar}}` to be at an indentation of 2 but was found at 0.'
result: {
rule: 'block-indentation',
message: 'Incorrect indentation for `{{bar}}` beginning at L3:C0. Expected `{{bar}}` to be at an indentation of 2 but was found at 0.',
moduleId: 'layout.hbs',
source: '<div>\n {{foo}}\n{{bar}}\n</div>',
line: 3,
column: 0
}
},

@@ -151,3 +201,10 @@ {

message: 'Incorrect indentation for `{{bar}}` beginning at (\'layout.hbs\'@ L3:C0). Expected `{{bar}}` to be at an indentation of 2 but was found at 0.'
result: {
rule: 'block-indentation',
message: 'Incorrect indentation for `{{bar}}` beginning at L3:C0. Expected `{{bar}}` to be at an indentation of 2 but was found at 0.',
moduleId: 'layout.hbs',
source: '<div>\n Foo:\n{{bar}}\n</div>',
line: 3,
column: 0
}
},

@@ -161,3 +218,11 @@ {

'</div>',
message: 'Incorrect indentation for `some-thing` beginning at (\'layout.hbs\'@ L2:C18). Expected `{{/some-thing}}` ending at (\'layout.hbs\'@ L3:C17) to be at an indentation of 18 but was found at 2.'
result: {
rule: 'block-indentation',
message: 'Incorrect indentation for `some-thing` beginning at L2:C18. Expected `{{/some-thing}}` ending at L3:C17 to be at an indentation of 18 but was found at 2.',
moduleId: 'layout.hbs',
source: '{{#some-thing}}\n {{/some-thing}}',
line: 3,
column: 17
}
},

@@ -172,5 +237,13 @@ {

'{{/if}}',
message: 'Incorrect indentation for `p` beginning at (\'layout.hbs\'@ L2:C10). Expected `</p>` ending at (\'layout.hbs\'@ L4:C6) to be at an indentation of 10 but was found at 2.'
result: {
rule: 'block-indentation',
message: 'Incorrect indentation for `p` beginning at L2:C10. Expected `</p>` ending at L4:C6 to be at an indentation of 10 but was found at 2.',
moduleId: 'layout.hbs',
source: '<p>\n Bar\n </p>',
line: 4,
column: 6
}
}
]
});

@@ -20,11 +20,25 @@ 'use strict';

template: '<!-- comment here -->',
message: 'Html comment detected `<!-- comment here -->` at (\'layout.hbs\'@ L1:C3). ' +
'Use Handlebars comment instead `{{!-- comment here --}}`'
result: {
rule: 'html-comments',
message: 'HTML comment detected',
moduleId: 'layout.hbs',
source: '<!-- comment here -->',
line: 1,
column: 3
}
},
{
template: '<!--comment here-->',
message: 'Html comment detected `<!--comment here-->` at (\'layout.hbs\'@ L1:C3). ' +
'Use Handlebars comment instead `{{!--comment here--}}`'
result: {
rule: 'html-comments',
message: 'HTML comment detected',
moduleId: 'layout.hbs',
source: '<!--comment here-->',
line: 1,
column: 3
}
}
]
});

@@ -57,17 +57,185 @@ 'use strict';

bad: [
{ config: ['a'], template: '<a href="/">button<a href="/">!</a></a>', message: 'Don\'t use <a> inside <a> (\'layout.hbs\'@ L1:C18)' },
{ config: ['a', 'button'], template: '<a href="/">button<button>!</button></a>', message: 'Don\'t use <button> inside <a> (\'layout.hbs\'@ L1:C18)' },
{ config: ['a', 'button'], template: '<button>button<a href="/">!</a></button>', message: 'Don\'t use <a> inside <button> (\'layout.hbs\'@ L1:C14)' },
{ config: ['button'], template: '<button>button<button>!</button></button>', message: 'Don\'t use <button> inside <button> (\'layout.hbs\'@ L1:C14)' },
{ config: ['button', 'input'], template: '<button><input type="text"></button>', message: 'Don\'t use <input> inside <button> (\'layout.hbs\'@ L1:C8)' },
{ config: ['button', 'details'], template: '<button><details><summary>Some details</summary><p>!</p></details></button>', message: 'Don\'t use <details> inside <button> (\'layout.hbs\'@ L1:C8)' },
{ config: ['button', 'embed'], template: '<button><embed type="video/quicktime" src="movie.mov" width="640" height="480"></button>', message: 'Don\'t use <embed> inside <button> (\'layout.hbs\'@ L1:C8)' },
{ config: ['button', 'iframe'], template: '<button><iframe src="/frame.html" width="640" height="480"></iframe></button>', message: 'Don\'t use <iframe> inside <button> (\'layout.hbs\'@ L1:C8)' },
{ config: ['button', 'select'], template: '<button><select></select></button>', message: 'Don\'t use <select> inside <button> (\'layout.hbs\'@ L1:C8)' },
{ config: ['button', 'textarea'], template: '<button><textarea></textarea></button>', message: 'Don\'t use <textarea> inside <button> (\'layout.hbs\'@ L1:C8)' },
{ config: ['button', 'tabindex'], template: '<div tabindex="1"><button></button></div>', message: 'Don\'t use <button> inside an element with attribute `tabindex` (\'layout.hbs\'@ L1:C18)' },
{ config: ['button', 'tabindex'], template: '<button><div tabindex="1"></div></button>', message: 'Don\'t use an element with attribute `tabindex` inside <button> (\'layout.hbs\'@ L1:C8)' },
{ config: ['button', 'img'], template: '<button><img usemap=""></button>', message: 'Don\'t use an element with attribute `usemap` inside <button> (\'layout.hbs\'@ L1:C8)' },
{ config: ['button', 'object'], template: '<object usemap=""><button></button></object>', message: 'Don\'t use <button> inside an element with attribute `usemap` (\'layout.hbs\'@ L1:C18)' }
{
config: ['a'],
template: '<a href="/">button<a href="/">!</a></a>',
result: {
rule: 'nested-interactive',
message: 'Do not use <a> inside <a>',
moduleId: 'layout.hbs',
source: '<a href=\"/\">!</a>',
line: 1,
column: 18
}
},
{
config: ['a', 'button'],
template: '<a href="/">button<button>!</button></a>',
result: {
rule: 'nested-interactive',
message: 'Do not use <button> inside <a>',
moduleId: 'layout.hbs',
source: '<button>!</button>',
line: 1,
column: 18
}
},
{
config: ['a', 'button'],
template: '<button>button<a href="/">!</a></button>',
result: {
rule: 'nested-interactive',
message: 'Do not use <a> inside <button>',
moduleId: 'layout.hbs',
source: '<a href=\"/\">!</a>',
line: 1,
column: 14
}
},
{
config: ['button'],
template: '<button>button<button>!</button></button>',
result: {
rule: 'nested-interactive',
message: 'Do not use <button> inside <button>',
moduleId: 'layout.hbs',
source: '<button>!</button>',
line: 1,
column: 14
}
},
{
config: ['button', 'input'],
template: '<button><input type="text"></button>',
result: {
rule: 'nested-interactive',
message: 'Do not use <input> inside <button>',
moduleId: 'layout.hbs',
source: '<input type="text">',
line: 1,
column: 8
}
},
{
config: ['button', 'details'],
template: '<button><details><summary>Some details</summary><p>!</p></details></button>',
result: {
rule: 'nested-interactive',
message: 'Do not use <details> inside <button>',
moduleId: 'layout.hbs',
source: '<details><summary>Some details</summary><p>!</p></details>',
line: 1,
column: 8
}
},
{
config: ['button', 'embed'],
template: '<button><embed type="video/quicktime" src="movie.mov" width="640" height="480"></button>',
result: {
rule: 'nested-interactive',
message: 'Do not use <embed> inside <button>',
moduleId: 'layout.hbs',
source: '<embed type=\"video/quicktime\" src=\"movie.mov\" width=\"640\" height=\"480\">',
line: 1,
column: 8
}
},
{
config: ['button', 'iframe'],
template: '<button><iframe src="/frame.html" width="640" height="480"></iframe></button>',
result: {
rule: 'nested-interactive',
message: 'Do not use <iframe> inside <button>',
moduleId: 'layout.hbs',
source: '<iframe src=\"/frame.html\" width=\"640\" height=\"480\"></iframe>',
line: 1,
column: 8
}
},
{
config: ['button', 'select'],
template: '<button><select></select></button>',
result: {
rule: 'nested-interactive',
message: 'Do not use <select> inside <button>',
moduleId: 'layout.hbs',
source: '<select></select>',
line: 1,
column: 8
}
},
{
config: ['button', 'textarea'],
template: '<button><textarea></textarea></button>',
result: {
rule: 'nested-interactive',
message: 'Do not use <textarea> inside <button>',
moduleId: 'layout.hbs',
source: '<textarea></textarea>',
line: 1,
column: 8
}
},
{
config: ['button', 'tabindex'],
template: '<div tabindex="1"><button></button></div>',
result: {
rule: 'nested-interactive',
message: 'Do not use <button> inside an element with attribute `tabindex`',
moduleId: 'layout.hbs',
source: '<button></button>',
line: 1,
column: 18
}
},
{
config: ['button', 'tabindex'],
template: '<button><div tabindex="1"></div></button>',
result: {
rule: 'nested-interactive',
message: 'Do not use an element with attribute `tabindex` inside <button>',
moduleId: 'layout.hbs',
source: '<div tabindex=\"1\"></div>',
line: 1,
column: 8
}
},
{
config: ['button', 'img'],
template: '<button><img usemap=""></button>',
result: {
rule: 'nested-interactive',
message: 'Do not use an element with attribute `usemap` inside <button>',
moduleId: 'layout.hbs',
source: '<img usemap=\"\">',
line: 1,
column: 8
}
},
{
config: ['button', 'object'],
template: '<object usemap=""><button></button></object>',
result: {
rule: 'nested-interactive',
message: 'Do not use <button> inside an element with attribute `usemap`',
moduleId: 'layout.hbs',
source: '<button></button>',
line: 1,
column: 18
}
}
]
});

@@ -17,4 +17,15 @@ 'use strict';

bad: [
{ template: '\n {{{foo}}}', message: 'Usage of triple curly brackets is unsafe `{{{foo}}}` at (\'layout.hbs\'@ L2:C1)' }
{
template: '\n {{{foo}}}',
result: {
rule: 'triple-curlies',
message: 'Usage of triple curly brackets is unsafe',
moduleId: 'layout.hbs',
source: '{{{foo}}}',
line: 2,
column: 1
}
}
]
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc