@salesforcedevs/sfdocs-liquid-lint-capture 0.0.4-alpha → 0.0.5-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,173 +1,76 @@
1
- # liquid-lint-capture
1
+ # @salesforcedevs/sfdocs-liquid-lint-capture
2
2
 
3
- This Markdown plugin validates the correct usage of Liquid capture blocks based on file location.
3
+ ## Overview
4
4
 
5
- ## What it checks
5
+ This plugin validates that Liquid `{% capture %}` blocks are only used in reusable partial files within the `shared/partials/` directory. Using capture blocks outside of partials results in warnings.
6
6
 
7
- ### For files in `shared/partials/`:
7
+ ### Features
8
8
 
9
- 1. **Content must be in capture blocks**: All markdown content (except comments) must be inside `{% capture %}` blocks
10
- 2. **No duplicate capture names**: Each capture variable name must be unique within the file
11
- 3. **Allowed content outside capture blocks**:
12
- - HTML comments: `<!-- comment -->`
13
- - Liquid comments: `{% comment %}...{% endcomment %}`
14
- - Whitespace
9
+ **Directory-Based Validation** - Warns when captures are outside `shared/partials/`
10
+ **Code Block Protection** - Ignores capture blocks inside markdown code blocks
11
+ **Accurate Line Numbers** - Reports exact location of violations
12
+ ✅ **Test Coverage** - Comprehensive test suite included
15
13
 
16
- ### For files outside `shared/partials/`:
14
+ ## Installation
17
15
 
18
- 1. **Capture blocks are not allowed**: Files outside the partials folder must not contain `{% capture %}` blocks
19
-
20
- ## Why
21
-
22
- Partial files in `shared/partials/` are reusable snippets that define Liquid variables via capture blocks. These variables are then consumed by other markdown files through includes. Enforcing this structure ensures:
23
-
24
- - Predictable variable definitions
25
- - No unintended content rendering
26
- - Prevent variable name collisions
27
- - Clear separation between partials and regular content
28
-
29
- Regular content files outside `shared/partials/` should not use capture blocks, as they are meant to render content directly, not define reusable variables. This validation prevents:
30
-
31
- - Misplaced variable definitions in content files
32
- - Confusion about file purpose and behavior
33
- - Accidental capture block usage outside the partials system
34
-
35
- ## Examples
36
-
37
- ### ✅ Valid
38
-
39
- **Single capture block:**
40
- ```markdown
41
- {% capture my_variable %}
42
- # Heading
43
-
44
- Content goes here.
45
- {% endcapture %}
16
+ ```bash
17
+ yarn add @salesforcedevs/sfdocs-liquid-lint-capture
46
18
  ```
47
19
 
48
- **Multiple captures with comments:**
49
- ```markdown
50
- <!-- This file defines common callouts -->
20
+ ## Usage
51
21
 
52
- {% comment %}Success message{% endcomment %}
53
- {% capture success_msg %}
54
- :::tip
55
- Operation completed successfully!
56
- :::
57
- {% endcapture %}
22
+ ### Basic Usage
58
23
 
59
- {% capture error_msg %}
60
- :::warning
61
- An error occurred.
62
- :::
63
- {% endcapture %}
64
- ```
24
+ Register the plugin in your `lintConfig.ts`:
65
25
 
66
- **Capture with whitespace control:**
67
- ```markdown
68
- {%- capture trimmed_content -%}
69
- No extra whitespace before/after
70
- {%- endcapture -%}
26
+ ```typescript
27
+ const internalPluginsConf = {
28
+ /**
29
+ * Warns when capture blocks are used outside shared/partials folder.
30
+ * Capture blocks should be in reusable partials.
31
+ */
32
+ 'liquid-capture-outside-partials': [
33
+ require('@salesforcedevs/sfdocs-liquid-lint-capture'),
34
+ ['warning']
35
+ ],
36
+ };
71
37
  ```
72
38
 
73
- ### ❌ Invalid
39
+ ## Rules
74
40
 
75
- **Content outside capture block:**
76
- ```markdown
77
- # This heading is not captured
41
+ ### Allowed: Capture blocks in `shared/partials/`
78
42
 
79
- {% capture my_var %}
80
- Captured content
81
- {% endcapture %}
82
- ```
83
- Error: `Content in shared/partials files must be inside capture blocks.`
43
+ Capture blocks are **allowed** in any file path containing `/shared/partials/`:
84
44
 
85
- **Duplicate capture names:**
86
45
  ```markdown
87
- {% capture my_variable %}
88
- First definition
89
- {% endcapture %}
46
+ <!-- File: /content/shared/partials/banner.md -->
90
47
 
91
- {% capture my_variable %}
92
- Duplicate definition
48
+ {% capture title %}
49
+ Welcome to our documentation
93
50
  {% endcapture %}
94
- ```
95
- Error: `Duplicate capture block name "my_variable". This variable already exists in file.`
96
51
 
97
- **Mixed issues:**
98
- ```markdown
99
- Regular paragraph outside capture.
100
-
101
- {% capture my_var %}First{% endcapture %}
102
- {% capture my_var %}Duplicate{% endcapture %}
103
- ```
104
- Errors:
105
- - `Content in shared/partials files must be inside capture blocks.`
106
- - `Duplicate capture block name "my_var"`
107
-
108
- ### ❌ Invalid (Files outside shared/partials)
109
-
110
- **Capture block in regular content file:**
111
- ```markdown
112
- # Guide Title
113
-
114
- {% capture my_variable %}
115
- Some content
52
+ {% capture description %}
53
+ Learn how to use our API
116
54
  {% endcapture %}
117
-
118
- Regular content here.
119
55
  ```
120
- Error: `Capture blocks are not allowed in files outside shared/partials folder.`
121
-
122
- ## File Scope
123
56
 
124
- This rule applies to **all** markdown files with different validation rules based on location:
57
+ **Output:** No warnings
125
58
 
126
- ### Files in `shared/partials/`:
127
- - **Must** use capture blocks for all content
128
- - **Must** have unique capture block names
129
- - `/content/shared/partials/common.md` ✅
130
- - `/docs/shared/partials/alerts.md` ✅
131
- - `shared/partials/buttons.md` ✅
59
+ ### ⚠️ Warning: Capture blocks outside `shared/partials/`
132
60
 
133
- ### Files outside `shared/partials/`:
134
- - **Must not** contain capture blocks
135
- - `/content/guides/example.md` ✅
136
- - `/shared/snippets/code.md` ✅
137
- - `docs/tutorials/intro.md` ✅
61
+ Capture blocks **trigger warnings** in files outside the partials directory:
138
62
 
139
- ## Install & build
140
-
141
- ```bash
142
- yarn install && yarn build
143
- ```
63
+ ```markdown
64
+ <!-- File: /content/guides/tutorial.md -->
144
65
 
145
- ## Testing
66
+ # Getting Started
146
67
 
147
- ```bash
148
- yarn test
68
+ {% capture intro %}
69
+ This is the introduction text
70
+ {% endcapture %}
149
71
  ```
150
72
 
151
- ## Usage
152
-
153
- In your unified pipeline:
154
-
155
- ```typescript
156
- import unified from 'unified';
157
- import parse from 'remark-parse';
158
- import liquidLintPartialsCapture from '@salesforcedevs/sfdocs-liquid-lint-capture';
159
-
160
- const processor = unified()
161
- .use(parse)
162
- .use(liquidLintPartialsCapture);
163
-
164
- const file = await processor.process(markdownContent);
165
-
166
- if (file.messages.length > 0) {
167
- file.messages.forEach(msg => {
168
- console.log(`${msg.line}:${msg.column}: ${msg.message}`);
169
- });
170
- }
73
+ **Output:**
171
74
  ```
172
-
173
- ---
75
+ 3:1 warning Capture blocks are not allowed in files outside shared/partials folder. Found capture block "intro". liquid-capture-outside-partials
76
+ ```
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <coverage generated="1781779022584" clover="3.2.0">
3
+ <project timestamp="1781779022584" name="All files">
4
+ <metrics statements="21" coveredstatements="21" conditionals="9" coveredconditionals="9" methods="3" coveredmethods="3" elements="33" coveredelements="33" complexity="0" loc="21" ncloc="21" packages="1" files="1" classes="1"/>
5
+ <file name="index.ts" path="/Users/sagarvk/Desktop/projects/sfdocs-lint/packages/liquid-lint-capture/src/index.ts">
6
+ <metrics statements="21" coveredstatements="21" conditionals="9" coveredconditionals="9" methods="3" coveredmethods="3"/>
7
+ <line num="5" count="1" type="stmt"/>
8
+ <line num="7" count="1" type="stmt"/>
9
+ <line num="9" count="1" type="stmt"/>
10
+ <line num="12" count="1" type="stmt"/>
11
+ <line num="21" count="31" type="stmt"/>
12
+ <line num="25" count="19" type="stmt"/>
13
+ <line num="26" count="19" type="stmt"/>
14
+ <line num="29" count="19" type="stmt"/>
15
+ <line num="30" count="19" type="stmt"/>
16
+ <line num="37" count="19" type="stmt"/>
17
+ <line num="42" count="32" type="cond" truecount="3" falsecount="0"/>
18
+ <line num="43" count="11" type="stmt"/>
19
+ <line num="46" count="21" type="cond" truecount="4" falsecount="0"/>
20
+ <line num="47" count="21" type="cond" truecount="1" falsecount="0"/>
21
+ <line num="49" count="19" type="stmt"/>
22
+ <line num="50" count="19" type="stmt"/>
23
+ <line num="52" count="19" type="cond" truecount="1" falsecount="0"/>
24
+ <line num="53" count="14" type="stmt"/>
25
+ <line num="54" count="19" type="stmt"/>
26
+ <line num="55" count="19" type="stmt"/>
27
+ <line num="64" count="1" type="stmt"/>
28
+ </file>
29
+ </project>
30
+ </coverage>
@@ -0,0 +1,2 @@
1
+ {"/Users/sagarvk/Desktop/projects/sfdocs-lint/packages/liquid-lint-capture/src/index.ts": {"path":"/Users/sagarvk/Desktop/projects/sfdocs-lint/packages/liquid-lint-capture/src/index.ts","statementMap":{"0":{"start":{"line":5,"column":0},"end":{"line":5,"column":37}},"1":{"start":{"line":7,"column":0},"end":{"line":7,"column":95}},"2":{"start":{"line":9,"column":15},"end":{"line":9,"column":50}},"3":{"start":{"line":12,"column":25},"end":{"line":12,"column":91}},"4":{"start":{"line":21,"column":4},"end":{"line":21,"column":50}},"5":{"start":{"line":25,"column":37},"end":{"line":25,"column":39}},"6":{"start":{"line":26,"column":15},"end":{"line":26,"column":55}},"7":{"start":{"line":29,"column":4},"end":{"line":35,"column":null}},"8":{"start":{"line":30,"column":8},"end":{"line":34,"column":11}},"9":{"start":{"line":37,"column":4},"end":{"line":37,"column":20}},"10":{"start":{"line":42,"column":4},"end":{"line":44,"column":null}},"11":{"start":{"line":43,"column":8},"end":{"line":43,"column":15}},"12":{"start":{"line":46,"column":16},"end":{"line":46,"column":43}},"13":{"start":{"line":47,"column":4},"end":{"line":47,"column":21}},"14":{"start":{"line":47,"column":14},"end":{"line":47,"column":21}},"15":{"start":{"line":49,"column":29},"end":{"line":49,"column":51}},"16":{"start":{"line":50,"column":26},"end":{"line":50,"column":64}},"17":{"start":{"line":52,"column":4},"end":{"line":60,"column":null}},"18":{"start":{"line":53,"column":8},"end":{"line":59,"column":null}},"19":{"start":{"line":54,"column":29},"end":{"line":54,"column":71}},"20":{"start":{"line":55,"column":12},"end":{"line":58,"column":14}},"21":{"start":{"line":64,"column":0},"end":{"line":64,"column":42}}},"fnMap":{"0":{"name":"isInPartialsFolder","decl":{"start":{"line":20,"column":9},"end":{"line":20,"column":27}},"loc":{"start":{"line":20,"column":44},"end":{"line":22,"column":1}}},"1":{"name":"extractCaptureBlocks","decl":{"start":{"line":24,"column":9},"end":{"line":24,"column":29}},"loc":{"start":{"line":24,"column":45},"end":{"line":38,"column":1}}},"2":{"name":"checkLiquidCapture","decl":{"start":{"line":40,"column":9},"end":{"line":40,"column":27}},"loc":{"start":{"line":40,"column":55},"end":{"line":62,"column":1}}}},"branchMap":{"0":{"loc":{"start":{"line":42,"column":4},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":44,"column":null}}]},"1":{"loc":{"start":{"line":42,"column":8},"end":{"line":42,"column":51}},"type":"binary-expr","locations":[{"start":{"line":42,"column":8},"end":{"line":42,"column":18}},{"start":{"line":42,"column":22},"end":{"line":42,"column":51}}]},"2":{"loc":{"start":{"line":46,"column":23},"end":{"line":46,"column":42}},"type":"cond-expr","locations":[{"start":{"line":46,"column":36},"end":{"line":46,"column":40}},{"start":{"line":46,"column":40},"end":{"line":46,"column":42}}]},"3":{"loc":{"start":{"line":46,"column":23},"end":{"line":46,"column":40}},"type":"binary-expr","locations":[{"start":{"line":46,"column":23},"end":{"line":46,"column":40}},{"start":{"line":46,"column":36},"end":{"line":46,"column":40}}]},"4":{"loc":{"start":{"line":47,"column":4},"end":{"line":47,"column":21}},"type":"if","locations":[{"start":{"line":47,"column":4},"end":{"line":47,"column":21}}]},"5":{"loc":{"start":{"line":52,"column":4},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":52,"column":4},"end":{"line":60,"column":null}}]}},"s":{"0":1,"1":1,"2":1,"3":1,"4":31,"5":19,"6":19,"7":19,"8":19,"9":19,"10":32,"11":11,"12":21,"13":21,"14":2,"15":19,"16":19,"17":19,"18":14,"19":19,"20":19,"21":1},"f":{"0":31,"1":19,"2":32},"b":{"0":[11],"1":[32,31],"2":[20,1],"3":[21,20],"4":[2],"5":[14]}}
2
+ }
@@ -0,0 +1,224 @@
1
+ body, html {
2
+ margin:0; padding: 0;
3
+ height: 100%;
4
+ }
5
+ body {
6
+ font-family: Helvetica Neue, Helvetica, Arial;
7
+ font-size: 14px;
8
+ color:#333;
9
+ }
10
+ .small { font-size: 12px; }
11
+ *, *:after, *:before {
12
+ -webkit-box-sizing:border-box;
13
+ -moz-box-sizing:border-box;
14
+ box-sizing:border-box;
15
+ }
16
+ h1 { font-size: 20px; margin: 0;}
17
+ h2 { font-size: 14px; }
18
+ pre {
19
+ font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
20
+ margin: 0;
21
+ padding: 0;
22
+ -moz-tab-size: 2;
23
+ -o-tab-size: 2;
24
+ tab-size: 2;
25
+ }
26
+ a { color:#0074D9; text-decoration:none; }
27
+ a:hover { text-decoration:underline; }
28
+ .strong { font-weight: bold; }
29
+ .space-top1 { padding: 10px 0 0 0; }
30
+ .pad2y { padding: 20px 0; }
31
+ .pad1y { padding: 10px 0; }
32
+ .pad2x { padding: 0 20px; }
33
+ .pad2 { padding: 20px; }
34
+ .pad1 { padding: 10px; }
35
+ .space-left2 { padding-left:55px; }
36
+ .space-right2 { padding-right:20px; }
37
+ .center { text-align:center; }
38
+ .clearfix { display:block; }
39
+ .clearfix:after {
40
+ content:'';
41
+ display:block;
42
+ height:0;
43
+ clear:both;
44
+ visibility:hidden;
45
+ }
46
+ .fl { float: left; }
47
+ @media only screen and (max-width:640px) {
48
+ .col3 { width:100%; max-width:100%; }
49
+ .hide-mobile { display:none!important; }
50
+ }
51
+
52
+ .quiet {
53
+ color: #7f7f7f;
54
+ color: rgba(0,0,0,0.5);
55
+ }
56
+ .quiet a { opacity: 0.7; }
57
+
58
+ .fraction {
59
+ font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
60
+ font-size: 10px;
61
+ color: #555;
62
+ background: #E8E8E8;
63
+ padding: 4px 5px;
64
+ border-radius: 3px;
65
+ vertical-align: middle;
66
+ }
67
+
68
+ div.path a:link, div.path a:visited { color: #333; }
69
+ table.coverage {
70
+ border-collapse: collapse;
71
+ margin: 10px 0 0 0;
72
+ padding: 0;
73
+ }
74
+
75
+ table.coverage td {
76
+ margin: 0;
77
+ padding: 0;
78
+ vertical-align: top;
79
+ }
80
+ table.coverage td.line-count {
81
+ text-align: right;
82
+ padding: 0 5px 0 20px;
83
+ }
84
+ table.coverage td.line-coverage {
85
+ text-align: right;
86
+ padding-right: 10px;
87
+ min-width:20px;
88
+ }
89
+
90
+ table.coverage td span.cline-any {
91
+ display: inline-block;
92
+ padding: 0 5px;
93
+ width: 100%;
94
+ }
95
+ .missing-if-branch {
96
+ display: inline-block;
97
+ margin-right: 5px;
98
+ border-radius: 3px;
99
+ position: relative;
100
+ padding: 0 4px;
101
+ background: #333;
102
+ color: yellow;
103
+ }
104
+
105
+ .skip-if-branch {
106
+ display: none;
107
+ margin-right: 10px;
108
+ position: relative;
109
+ padding: 0 4px;
110
+ background: #ccc;
111
+ color: white;
112
+ }
113
+ .missing-if-branch .typ, .skip-if-branch .typ {
114
+ color: inherit !important;
115
+ }
116
+ .coverage-summary {
117
+ border-collapse: collapse;
118
+ width: 100%;
119
+ }
120
+ .coverage-summary tr { border-bottom: 1px solid #bbb; }
121
+ .keyline-all { border: 1px solid #ddd; }
122
+ .coverage-summary td, .coverage-summary th { padding: 10px; }
123
+ .coverage-summary tbody { border: 1px solid #bbb; }
124
+ .coverage-summary td { border-right: 1px solid #bbb; }
125
+ .coverage-summary td:last-child { border-right: none; }
126
+ .coverage-summary th {
127
+ text-align: left;
128
+ font-weight: normal;
129
+ white-space: nowrap;
130
+ }
131
+ .coverage-summary th.file { border-right: none !important; }
132
+ .coverage-summary th.pct { }
133
+ .coverage-summary th.pic,
134
+ .coverage-summary th.abs,
135
+ .coverage-summary td.pct,
136
+ .coverage-summary td.abs { text-align: right; }
137
+ .coverage-summary td.file { white-space: nowrap; }
138
+ .coverage-summary td.pic { min-width: 120px !important; }
139
+ .coverage-summary tfoot td { }
140
+
141
+ .coverage-summary .sorter {
142
+ height: 10px;
143
+ width: 7px;
144
+ display: inline-block;
145
+ margin-left: 0.5em;
146
+ background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
147
+ }
148
+ .coverage-summary .sorted .sorter {
149
+ background-position: 0 -20px;
150
+ }
151
+ .coverage-summary .sorted-desc .sorter {
152
+ background-position: 0 -10px;
153
+ }
154
+ .status-line { height: 10px; }
155
+ /* yellow */
156
+ .cbranch-no { background: yellow !important; color: #111; }
157
+ /* dark red */
158
+ .red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
159
+ .low .chart { border:1px solid #C21F39 }
160
+ .highlighted,
161
+ .highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
162
+ background: #C21F39 !important;
163
+ }
164
+ /* medium red */
165
+ .cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
166
+ /* light red */
167
+ .low, .cline-no { background:#FCE1E5 }
168
+ /* light green */
169
+ .high, .cline-yes { background:rgb(230,245,208) }
170
+ /* medium green */
171
+ .cstat-yes { background:rgb(161,215,106) }
172
+ /* dark green */
173
+ .status-line.high, .high .cover-fill { background:rgb(77,146,33) }
174
+ .high .chart { border:1px solid rgb(77,146,33) }
175
+ /* dark yellow (gold) */
176
+ .status-line.medium, .medium .cover-fill { background: #f9cd0b; }
177
+ .medium .chart { border:1px solid #f9cd0b; }
178
+ /* light yellow */
179
+ .medium { background: #fff4c2; }
180
+
181
+ .cstat-skip { background: #ddd; color: #111; }
182
+ .fstat-skip { background: #ddd; color: #111 !important; }
183
+ .cbranch-skip { background: #ddd !important; color: #111; }
184
+
185
+ span.cline-neutral { background: #eaeaea; }
186
+
187
+ .coverage-summary td.empty {
188
+ opacity: .5;
189
+ padding-top: 4px;
190
+ padding-bottom: 4px;
191
+ line-height: 1;
192
+ color: #888;
193
+ }
194
+
195
+ .cover-fill, .cover-empty {
196
+ display:inline-block;
197
+ height: 12px;
198
+ }
199
+ .chart {
200
+ line-height: 0;
201
+ }
202
+ .cover-empty {
203
+ background: white;
204
+ }
205
+ .cover-full {
206
+ border-right: none !important;
207
+ }
208
+ pre.prettyprint {
209
+ border: none !important;
210
+ padding: 0 !important;
211
+ margin: 0 !important;
212
+ }
213
+ .com { color: #999 !important; }
214
+ .ignore-none { color: #999; font-weight: normal; }
215
+
216
+ .wrapper {
217
+ min-height: 100%;
218
+ height: auto !important;
219
+ height: 100%;
220
+ margin: 0 auto -48px;
221
+ }
222
+ .footer, .push {
223
+ height: 48px;
224
+ }
@@ -0,0 +1,87 @@
1
+ /* eslint-disable */
2
+ var jumpToCode = (function init() {
3
+ // Classes of code we would like to highlight in the file view
4
+ var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no'];
5
+
6
+ // Elements to highlight in the file listing view
7
+ var fileListingElements = ['td.pct.low'];
8
+
9
+ // We don't want to select elements that are direct descendants of another match
10
+ var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > `
11
+
12
+ // Selector that finds elements on the page to which we can jump
13
+ var selector =
14
+ fileListingElements.join(', ') +
15
+ ', ' +
16
+ notSelector +
17
+ missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b`
18
+
19
+ // The NodeList of matching elements
20
+ var missingCoverageElements = document.querySelectorAll(selector);
21
+
22
+ var currentIndex;
23
+
24
+ function toggleClass(index) {
25
+ missingCoverageElements
26
+ .item(currentIndex)
27
+ .classList.remove('highlighted');
28
+ missingCoverageElements.item(index).classList.add('highlighted');
29
+ }
30
+
31
+ function makeCurrent(index) {
32
+ toggleClass(index);
33
+ currentIndex = index;
34
+ missingCoverageElements.item(index).scrollIntoView({
35
+ behavior: 'smooth',
36
+ block: 'center',
37
+ inline: 'center'
38
+ });
39
+ }
40
+
41
+ function goToPrevious() {
42
+ var nextIndex = 0;
43
+ if (typeof currentIndex !== 'number' || currentIndex === 0) {
44
+ nextIndex = missingCoverageElements.length - 1;
45
+ } else if (missingCoverageElements.length > 1) {
46
+ nextIndex = currentIndex - 1;
47
+ }
48
+
49
+ makeCurrent(nextIndex);
50
+ }
51
+
52
+ function goToNext() {
53
+ var nextIndex = 0;
54
+
55
+ if (
56
+ typeof currentIndex === 'number' &&
57
+ currentIndex < missingCoverageElements.length - 1
58
+ ) {
59
+ nextIndex = currentIndex + 1;
60
+ }
61
+
62
+ makeCurrent(nextIndex);
63
+ }
64
+
65
+ return function jump(event) {
66
+ if (
67
+ document.getElementById('fileSearch') === document.activeElement &&
68
+ document.activeElement != null
69
+ ) {
70
+ // if we're currently focused on the search input, we don't want to navigate
71
+ return;
72
+ }
73
+
74
+ switch (event.which) {
75
+ case 78: // n
76
+ case 74: // j
77
+ goToNext();
78
+ break;
79
+ case 66: // b
80
+ case 75: // k
81
+ case 80: // p
82
+ goToPrevious();
83
+ break;
84
+ }
85
+ };
86
+ })();
87
+ window.addEventListener('keydown', jumpToCode);
Binary file