Skip to content

Commit e0eecc0

Browse files
alecmerdleroutoftime
authored andcommitted
add 'href-style' validation to prevent relative links (#1602)
1 parent 425e6d4 commit e0eecc0

5 files changed

Lines changed: 14 additions & 3 deletions

File tree

locales/en/translation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
"doctype": "The first line of your HTML should always be:\n`<!DOCTYPE html>`",
131131
"duplicated-id": "You can't use the id \"{{-id}}\" more than once in your HTML",
132132
"img-src": "`<img>` tags need a `src` attribute, with the URL of the image you want to display.",
133+
"href-style": "The `<a>` tag should have an `href` attribute that starts with 'http' or 'https'",
133134
"deprecated-tag": {
134135
"b": "You shouldn't use the `<b>` tag. Use the `<strong>` tag or the CSS `font-weight` property instead",
135136
"big": "You shouldn't use the `<big>` tag. Use the CSS `font-size` property instead",

src/validations/html/htmllint.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ const errorMap = {
4646

4747
E008: () => ({reason: 'doctype'}),
4848

49+
E009: () => ({reason: 'href-style'}),
50+
4951
E012: error => ({reason: 'duplicated-id', payload: {id: error.data.id}}),
5052

5153
E014: () => ({reason: 'img-src'}),
@@ -134,6 +136,7 @@ const htmlLintOptions = {
134136
'tag-name-lowercase': true,
135137
'tag-self-close': 'never',
136138
'title-no-dup': true,
139+
'href-style': 'absolute',
137140
};
138141

139142
const linter = new Linter(rules);

test/data/acceptance.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"html": [
3-
"<!DOCTYPE html>\n<html>\n <head>\n <title>Unit 1, Project 1</title>\n </head>\n <body>\n <h1>I love ScriptEd!</h1>\n <img src=\"http://i.imgur.com/J5ji6zX.png\">\n <p>This is the ScriptEd logo</p>\n <a href=\"www.scripted.org\">This is a link to ScriptEd's website </a>\n \n <img src=\"http://i.imgur.com/EwUGnTi.png\">\n <p>In ScriptEd we learn the HTML, CSS and JavaScript</p>\n <a href=\"https://github.com/ScriptEdcurriculum/curriculum2016\">This is a link to ScriptEd's curriculum </a>\n </body>\n</html>\n",
4-
"<!DOCTYPE html>\n<html>\n <head>\n <title>Unit 1, Project 1</title>\n </head>\n <body>\n <h1>I love ScriptEd!</h1>\n <img src=\"http://i.imgur.com/J5ji6zX.png\">\n <p>This is the ScriptEd logo</p>\n <a href=\"www.scripted.org\">This is a link to ScriptEd's website </a>\n \n <img src=\"http://i.imgur.com/EwUGnTi.png\">\n <p>In ScriptEd we learn the HTML, CSS and JavaScript</p>\n <a href=\"https://github.com/ScriptEdcurriculum/curriculum2016\">This is a link to ScriptEd's curriculum </a>\n </body>\n</html>\n",
3+
"<!DOCTYPE html>\n<html>\n <head>\n <title>Unit 1, Project 1</title>\n </head>\n <body>\n <h1>I love ScriptEd!</h1>\n <img src=\"http://i.imgur.com/J5ji6zX.png\">\n <p>This is the ScriptEd logo</p>\n <a href=\"https://www.scripted.org\">This is a link to ScriptEd's website </a>\n \n <img src=\"http://i.imgur.com/EwUGnTi.png\">\n <p>In ScriptEd we learn the HTML, CSS and JavaScript</p>\n <a href=\"https://github.com/ScriptEdcurriculum/curriculum2016\">This is a link to ScriptEd's curriculum </a>\n </body>\n</html>\n",
4+
"<!DOCTYPE html>\n<html>\n <head>\n <title>Unit 1, Project 1</title>\n </head>\n <body>\n <h1>I love ScriptEd!</h1>\n <img src=\"http://i.imgur.com/J5ji6zX.png\">\n <p>This is the ScriptEd logo</p>\n <a href=\"https://www.scripted.org\">This is a link to ScriptEd's website </a>\n \n <img src=\"http://i.imgur.com/EwUGnTi.png\">\n <p>In ScriptEd we learn the HTML, CSS and JavaScript</p>\n <a href=\"https://github.com/ScriptEdcurriculum/curriculum2016\">This is a link to ScriptEd's curriculum </a>\n </body>\n</html>\n",
55
"<!DOCTYPE html>\n<html>\n <head>\n <title>Grace Hopper</title>\n <link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">\n </head>\n <body>\n <h1 id=\"title\">This page is about me</h1>\n <p id=\"name\">My name is Grace Hopper</p>\n <p id=\"job\">I work in the NAVY as a programmer</p>\n <p id=\"fun\">For fun, I research how to write new machine programs</p>\n <p id=\"movie\">My favorite movie is \"Hamlet\"</p>\n <p id=\"music\">My favorite type of music is jazz</p>\n <p id=\"year\">In ten years I hope to be creating more complex programs that help the Navy</p>\n <a href=\"https://en.wikipedia.org/wiki/Grace_Hopper\">Here is a link to my Wikipedia page</a>\n <div id=\"image\"><img src=\"https://media1.britannica.com/eb-media/00/149300-004-D49D0778.jpg\"></div>\n </body>\n</html>\n",
66
"<!DOCTYPE html>\n<html>\n <head>\n <title>ScriptEd CSS Garden</title>\n </head>\n <body>\n <h1 id=\"banner\">ScriptEd CSS Site!</h1>\n <h1 id=\"tagline\">We love ScriptEd</h1>\n <img src=\"http://i65.tinypic.com/qxvr46.jpg\">\n\n <p id=\"mission\">ScriptEd equips students with the fundamental coding skills and professional experiences that together create access to careers in technology.</p>\n <p id=\"about\"> This year in ScriptEd we are going to create several websites, games and webapps! </p>\n <h1 id=\"topics\"> In ScriptEd we learn...</h1>\n <ul>\n <li>HTML</li>\n <li>CSS</li>\n <li>JavaScript</li>\n <li>Git</li>\n <li>jQuery</li>\n </ul>\n </body>\n</html>\n",
77
"<!DOCTYPE html>\n<html>\n <head>\n <title>jQuery Puns</title>\n </head>\n <body>\n <h1>ScriptEd Pun-A-Thon</h1>\n <hr>\n <div id=\"joke-1\"> What kind of cheese doesn't belong to you?\n <button>Click</button>\n </div>\n <hr>\n <div id=\"joke-2\"> What does the annoying pepper do? \n <button>Click</button>\n </div>\n <hr>\n <div id=\"joke-3\">\n <p> Why did the bike fall over? </p>\n <button>Click</button>\n </div>\n <hr>\n <img id=\"joke-4\" src=\"http://i.imgur.com/tWNHJEV.jpg\">\n</body>\n</html>\n",

test/helpers/testValidatorAcceptance.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import validationTest from './validationTest';
55
export default function testValidatorAcceptance(validator, language) {
66
return (t) => {
77
acceptance[language].forEach(
8-
source => t.test(validationTest(source, validator)),
8+
source => t.test(`Acceptance - ${language}`,
9+
validationTest(source, validator)),
910
);
1011
};
1112
}

test/unit/validations/html.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ test('void tags without explicit close', validationTest(
4141
html,
4242
));
4343

44+
test('<a> tag with relative href property', validationTest(
45+
htmlWithBody('<a href="./foo.bar">Bad link</a>'),
46+
html,
47+
{reason: 'href-style', row: htmlWithBody.offset},
48+
));
49+
4450
test('missing doctype', validationTest(
4551
'<p>T</p>',
4652
html,

0 commit comments

Comments
 (0)