Skip to content

Commit

Permalink
custom-element-name: Show warnings based on best practices
Browse files Browse the repository at this point in the history
Closes #29.
  • Loading branch information
mathiasbynens committed Apr 7, 2014
1 parent a4c77f4 commit bd4d163
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 46 deletions.
11 changes: 8 additions & 3 deletions custom-element-name/eff.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ i {
padding-bottom: 0;
}

#valid.show, #invalid.show {
#valid.show, #message.show {
display: block;
}

#valid.hide, #invalid.hide {
#valid.hide, #message.hide {
display: none;
}

Expand All @@ -60,6 +60,11 @@ pre {
background: #ffb6c1;
}

.warning {
border-color: #f89406;
background: #fdfd9a;
}

input {
width: 100%;
-moz-box-sizing: border-box;
Expand Down Expand Up @@ -103,4 +108,4 @@ code, input {
border-width: 0 1px;
}

}
}
25 changes: 16 additions & 9 deletions custom-element-name/eff.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

var input = document.getElementsByTagName('input')[0];
var valid = window.valid;
var invalid = window.invalid;
var message = window.message;
var permalink = document.getElementById('permalink');
// http://mathiasbynens.be/notes/localstorage-pattern
var storage = (function() {
Expand All @@ -27,17 +27,24 @@

function update() {
var value = input.value;
try {
var result = validate(value);
if (result.isValid) {
validate(value);
valid.className = 'show';
invalid.className = 'hide';
input.className = 'valid';
} catch(exception) {
// Note: the use of `innerHTML` is intended and safe in this case, since
// we fully control the error messages.
invalid.innerHTML = exception.message;
if (result.message) {
input.className = 'warning';
// Note: the use of `innerHTML` is intended and safe in this case,
// since we fully control the error messages.
message.innerHTML = '<em>However</em>, as a best practice, ' + result.message;
message.className = 'show';
} else {
input.className = 'valid';
message.className = 'hide';
}
} else {
message.innerHTML = result.message;
message.className = 'show';
valid.className = 'hide';
invalid.className = 'show';
input.className = 'invalid';
}
permalink.hash = encode(value);
Expand Down
2 changes: 1 addition & 1 deletion custom-element-name/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ <h1>Custom HTML element name validator</h1>
<noscript><strong>To use this tool, please <a href=http://enable-javascript.com/>enable JavaScript</a> and reload the page.</strong></noscript>
<a href=#yolo-swag id=permalink>permalink</a> <label>Enter a variable name: <input value=yolo-swag required autofocus placeholder="e.g. kitchensink"></label>
<p id=valid>That’s <i>a valid</i> custom element name.
<p id=invalid class=hide>That’s <i>an invalid</i> custom element name.
<p id=message class=hide>
<h2>About this tool</h2>
<p>This tool uses <a href=http://sindresorhus.com/>Sindre Sorhus</a>’s <a href=https://github.com/sindresorhus/validate-element-name><i>validate-element-name</i></a> under the hood.
<p id=footer>Made by <a href=http://mathiasbynens.be/>@mathias</a><a href=https://github.com/mathiasbynens/mothereff.in/tree/master/custom-element-name>fork this on GitHub!</a></p>
Expand Down
57 changes: 40 additions & 17 deletions custom-element-name/vendor/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
// http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName
var ncname = new RegExp('^[' + getRange(xmlChars.letter) + '_][' + getRange(xmlChars.letter) + getRange(xmlChars.digit) + '\\.\\-_' + getRange(xmlChars.combiningChar) + getRange(xmlChars.extender) + ']*$');


var reservedNames = [
'annotation-xml',
'color-profile',
Expand All @@ -28,45 +27,69 @@
'missing-glyph'
];

window.validate = function(name) {
function hasError(name) {
if (!name) {
throw new Error('Missing element name.');
return 'Missing element name.';
}

if (name.indexOf('-') === -1) {
throw new Error('Custom element names must contain a hyphen. Example: <code>unicorn-cake</code>.');
return 'Custom element names must contain a hyphen. Example: <code>unicorn-cake</code>.';
}

if (/^\d/i.test(name)) {
return 'Custom element names must not start with a digit.';
}

if (/^-/i.test(name)) {
return 'Custom element names must not start with a hyphen.';
}

// http://www.w3.org/TR/custom-elements/#concepts
if (!ncname.test(name)) {
return 'Invalid element name.';
}

if (reservedNames.indexOf(name) !== -1) {
return 'The supplied element name is reserved and can’t be used.\nSee <a href=http://www.w3.org/TR/custom-elements/#concepts>“Custom Elements Specification: Concepts”</a>.';
}
};

function hasWarning(name) {
if (/^polymer-/.test(name)) {
throw new Error('Custom element names should not start with <code>polymer-</code>.\nSee <a href=http://webcomponents.github.io/articles/how-should-i-name-my-element>“How should I name my element?”</a>.');
return 'custom element names should not start with <code>polymer-</code>.\nSee <a href=http://webcomponents.github.io/articles/how-should-i-name-my-element>“How should I name my element?”</a>.';
}

if (/^x-/.test(name)) {
throw new Error('Custom element names should not start with <code>x-</code>.\nSee <a href=http://webcomponents.github.io/articles/how-should-i-name-my-element>“How should I name my element?”</a>.');
return 'custom element names should not start with <code>x-</code>.\nSee <a href=http://webcomponents.github.io/articles/how-should-i-name-my-element>“How should I name my element?”</a>.';
}

if (/^ng-/.test(name)) {
throw new Error('Custom element names should not start with <code>ng-</code>.\nSee <a href=http://docs.angularjs.org/guide/directive#creating-directives>“How to create an AngularJS directive”</a>.');
return 'custom element names should not start with <code>ng-</code>.\nSee <a href=http://docs.angularjs.org/guide/directive#creating-directives>“How to create an AngularJS directive”</a>.';
}

if (/^\d/i.test(name)) {
throw new Error('Custom element names must not start with a digit.');
if (/-$/.test(name)) {
return 'custom element names should not end with an hyphen.';
}

if (/^-/i.test(name)) {
throw new Error('Custom element names must not start with a hyphen.');
if (/[^\x20-\x7E]/.test(name)) {
return 'custom element names should not contain non-ASCII characters.';
}

// http://www.w3.org/TR/custom-elements/#concepts
if (!ncname.test(name)) {
throw new Error('Invalid element name.');
if (/--/.test(name)) {
return 'custom element names should not contain consecutive hyphens.';
}

if (reservedNames.indexOf(name) !== -1) {
throw new Error('The supplied element name is reserved and can’t be used.\nSee <a href=http://www.w3.org/TR/custom-elements/#concepts>“Custom Elements Specification: Concepts”</a>.');
if (/[^a-z0-9]{2}/.test(name)) {
return 'custom element names should not contain consecutive non-alpha characters.';
}
}

return true;
window.validate = function(name) {
var errMsg = hasError(name);
return {
'isValid': !errMsg,
'message': errMsg || hasWarning(name)
};
};

}());
57 changes: 41 additions & 16 deletions custom-element-name/vendor/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,68 @@ var reservedNames = [
'missing-glyph'
];

module.exports = function (name) {
function hasError(name) {
if (!name) {
throw new Error('Missing element name');
return 'Missing element name.';
}

if (name.indexOf('-') === -1) {
throw new Error('Custom element names must contain a hyphen. Example: unicorn-cake');
return 'Custom element names must contain a hyphen. Example: unicorn-cake';
}

if (/^\d/i.test(name)) {
return 'Custom element names must not start with a digit.';
}

if (/^-/i.test(name)) {
return 'Custom element names must not start with a hyphen.';
}

// http://www.w3.org/TR/custom-elements/#concepts
if (!ncname.test(name)) {
return 'Invalid element name.';
}

if (reservedNames.indexOf(name) !== -1) {
return 'The supplied element name is reserved and can\'t be used.\nSee: http://www.w3.org/TR/custom-elements/#concepts';
}
};

function hasWarning(name) {
if (/^polymer-/.test(name)) {
throw new Error('Custom element names should not start with `polymer-`.\nSee: http://webcomponents.github.io/articles/how-should-i-name-my-element');
return 'Custom element names should not start with `polymer-`.\nSee: http://webcomponents.github.io/articles/how-should-i-name-my-element';
}

if (/^x-/.test(name)) {
throw new Error('Custom element names should not start with `x-`.\nSee: http://webcomponents.github.io/articles/how-should-i-name-my-element/');
return 'Custom element names should not start with `x-`.\nSee: http://webcomponents.github.io/articles/how-should-i-name-my-element/';
}

if (/^ng-/.test(name)) {
throw new Error('Custom element names should not start with `ng-`.\nSee: http://docs.angularjs.org/guide/directive#creating-directives');
return 'Custom element names should not start with `ng-`.\nSee: http://docs.angularjs.org/guide/directive#creating-directives';
}

if (/^\d/i.test(name)) {
throw new Error('Custom element names must not start with a digit');
if (/-$/.test(name)) {
return 'Custom element names should not end with an hyphen.';
}

if (/^-/i.test(name)) {
throw new Error('Custom element names must not start with a hyphen');
if (/[^\x20-\x7E]+/.test(name)) {
return 'Custom element names should not contain non-ASCII characters.';
}

// http://www.w3.org/TR/custom-elements/#concepts
if (!ncname.test(name)) {
throw new Error('Invalid element name.');
if (/--/.test(name)) {
return 'Custom element names should not contain consecutive hyphens.';
}

if (reservedNames.indexOf(name) !== -1) {
throw new Error('The supplied element name is reserved and can\'t be used.\nSee: http://www.w3.org/TR/custom-elements/#concepts');
if (/[^a-z0-9]{2}/.test(name)) {
return 'Custom element names should not contain consecutive non-alpha characters.';
}
}

module.exports = function (name) {
var errMsg = hasError(name);

return true;
return {
isValid: !errMsg,
message: errMsg || hasWarning(name)
};
};

0 comments on commit bd4d163

Please sign in to comment.