Skip to content

Commit 38040a7

Browse files
committed
Chore: add require-noopener rule
1 parent 3bf08f6 commit 38040a7

File tree

7 files changed

+52
-6
lines changed

7 files changed

+52
-6
lines changed

.eslintrc.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
"node/no-missing-import": "error",
2929
"node/no-unpublished-import": "error",
3030
"vue/html-indent": ["error", 4],
31-
"vue/max-attributes-per-line": "off"
31+
"vue/max-attributes-per-line": "off",
32+
33+
"require-noopener": "error"
3234
}
3335
}

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@
22
"eslint.validate": [
33
"javascript",
44
{"autoFix": true, "language": "vue"}
5-
]
5+
],
6+
"eslint.options": {
7+
"rulePaths": ["eslint-rules"]
8+
}
69
}

eslint-rules/.eslintrc.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"root": true,
3+
"extends": [
4+
"mysticatea",
5+
"mysticatea/node"
6+
],
7+
"rules": {
8+
"no-console": "off"
9+
}
10+
}

eslint-rules/require-noopener.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"use strict"
2+
3+
module.exports = (context) =>
4+
context.parserServices.defineTemplateBodyVisitor({
5+
"VElement[name='a']"(node) {
6+
const attributes = node.startTag.attributes
7+
const hasTargetBlank = attributes.some(attribute =>
8+
!attribute.directive &&
9+
attribute.key.name === "target" &&
10+
attribute.value != null &&
11+
attribute.value.value === "_blank"
12+
)
13+
const hasRelNoopener = attributes.some(attribute =>
14+
!attribute.directive &&
15+
attribute.key.name === "rel" &&
16+
attribute.value != null &&
17+
attribute.value.value === "noopener"
18+
)
19+
20+
if (hasTargetBlank && !hasRelNoopener) {
21+
context.report({
22+
node: node.startTag,
23+
message: "Use 'rel=\"noopener\" to open new tab.",
24+
* fix(fixer) {
25+
const lastAttribute = attributes[attributes.length - 1]
26+
yield fixer.insertTextAfter(lastAttribute, " rel=\"noopener\"")
27+
},
28+
})
29+
}
30+
},
31+
})

src/app.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div class="app__root">
33
<div class="app__header">
44
<div class="app__header-title">
5-
Playground for <a href="https://github.com/vuejs/eslint-plugin-vue#readme" target="_blank">eslint-plugin-vue</a>.
5+
Playground for <a href="https://github.com/vuejs/eslint-plugin-vue#readme" target="_blank" rel="noopener">eslint-plugin-vue</a>.
66
</div>
77
<label class="app__header-option-item">
88
<select v-model.number="indentSize">
@@ -54,7 +54,7 @@
5454
v-for="(v, name) in versions"
5555
:key="name"
5656
>
57-
<a :href="'https://github.com/' + v.repo" target="_blank">{{ name }}</a>
57+
<a :href="'https://github.com/' + v.repo" target="_blank" rel="noopener">{{ name }}</a>
5858
v{{ v.version }}
5959
</div>
6060
</div>

src/message-list.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
:key="i"
1515
>
1616
<md-icon kind="warning"/>
17-
{{ m.line }}:{{ m.column }}{{ space(m) }}{{ m.message }} (<a :href="url(m.ruleId)" target="_blank" v-if="m.ruleId != null">{{ m.ruleId }}</a><span v-else>FATAL</span>)
17+
{{ m.line }}:{{ m.column }}{{ space(m) }}{{ m.message }} (<a :href="url(m.ruleId)" target="_blank" v-if="m.ruleId != null" rel="noopener">{{ m.ruleId }}</a><span v-else>FATAL</span>)
1818
</li>
1919
</ul>
2020
</template>

src/rule-select-category.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<div class="rule-select-category__rule-name">
4343
{{ stripPrefix(rule.name) }}
4444
</div>
45-
<a class="rule-select-category__rule-link" :href="url(rule.name)" target="_blank">
45+
<a class="rule-select-category__rule-link" :href="url(rule.name)" target="_blank" rel="noopener">
4646
<md-icon kind="launch" title="Open document"/>
4747
</a>
4848
</label>

0 commit comments

Comments
 (0)