Skip to content

Commit 9f682a1

Browse files
author
Jesse Haigh
committed
add strikethrough lines
1 parent 66f0ae1 commit 9f682a1

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

src/components/ContentNode.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ function renderNode(createElement, references) {
277277
copyToClipboard: node.copyToClipboard ?? false,
278278
wrap: node.wrap ?? 0,
279279
highlightedLines: node.highlight ?? [],
280+
strikethroughLines: node.strikeout ?? [],
280281
};
281282
return createElement(CodeListing, { props });
282283
}

src/components/ContentNode/CodeListing.vue

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
><span
4343
:key="index"
4444
:class="['code-line-container',{ highlighted: isHighlighted(index),
45-
'user-highlighted': isUserHighlighted(index) }]"
45+
'user-highlighted': isUserHighlighted(index),
46+
'user-strikethrough': isUserStrikethrough(index),}]"
4647
><span
4748
v-if="showLineNumbers"
4849
class="code-number"
@@ -113,6 +114,10 @@ export default {
113114
type: Array,
114115
default: () => [],
115116
},
117+
strikethroughLines: {
118+
type: Array,
119+
default: () => [],
120+
},
116121
startLineNumber: {
117122
type: Number,
118123
default: () => 1,
@@ -143,6 +148,10 @@ export default {
143148
const arr = this.highlightedLines || [];
144149
return new Set(arr.map(Number).filter(n => Number.isFinite(n) && n > 0));
145150
},
151+
strikethroughSet() {
152+
const arr = this.strikethroughLines || [];
153+
return new Set(arr.map(Number).filter(n => Number.isFinite(n) && n > 0));
154+
},
146155
wrapStyle() {
147156
const style = {};
148157
if (this.wrap > 0) {
@@ -169,6 +178,9 @@ export default {
169178
isUserHighlighted(index) {
170179
return this.highlightSet.has(this.lineNumberFor(index));
171180
},
181+
isUserStrikethrough(index) {
182+
return this.strikethroughSet.has(this.lineNumberFor(index));
183+
},
172184
// Returns the line number for the line at the given index in `content`.
173185
lineNumberFor(index) {
174186
return this.startLineNumber + index;
@@ -247,6 +259,12 @@ export default {
247259
}
248260
}
249261
262+
.user-strikethrough {
263+
text-decoration-line: line-through;
264+
text-decoration-color: var(--color-figure-gray);
265+
opacity: 0.85;
266+
}
267+
250268
pre {
251269
padding: $code-listing-with-numbers-padding;
252270
display: flex;

tests/unit/components/ContentNode.spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ describe('ContentNode', () => {
102102
fileType: 'swift',
103103
code: ['foobar'],
104104
copyToClipboard: false,
105+
wrap: 0,
106+
highlightedLines: [],
107+
strikethroughLines: [],
105108
};
106109

107110
it('renders a `CodeListing`', () => {
@@ -113,6 +116,9 @@ describe('ContentNode', () => {
113116
expect(codeListing.props('fileType')).toBe(listing.fileType);
114117
expect(codeListing.props('content')).toEqual(listing.code);
115118
expect(codeListing.props('copyToClipboard')).toEqual(listing.copyToClipboard);
119+
expect(codeListing.props('wrap')).toEqual(listing.wrap);
120+
expect(codeListing.props('highlightedLines')).toEqual(listing.highlightedLines);
121+
expect(codeListing.props('strikethroughLines')).toEqual(listing.strikethroughLines);
116122
expect(codeListing.isEmpty()).toBe(true);
117123
});
118124

tests/unit/components/ContentNode/CodeListing.spec.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,76 @@ describe('CodeListing', () => {
9797
});
9898
});
9999

100+
it('highlights the correct lines from highlightedLines', async () => {
101+
const content = ['a', 'b', 'c', 'd', 'e'];
102+
const highlightedLines = [1, 3];
103+
104+
const wrapper = shallowMount(CodeListing, {
105+
propsData: {
106+
content,
107+
highlightedLines,
108+
showLineNumbers: true,
109+
},
110+
});
111+
112+
await flushPromises();
113+
114+
const pre = wrapper.find('pre');
115+
expect(pre.exists()).toBe(true);
116+
117+
const codeLineContainers = wrapper.findAll('span.code-line-container');
118+
expect(codeLineContainers.length).toBe(content.length);
119+
120+
content.forEach((line, index) => {
121+
const codeLineContainer = codeLineContainers.at(index);
122+
const shouldBeHighlighted = highlightedLines.includes(index + 1);
123+
124+
const codeNumber = codeLineContainer.find('.code-number');
125+
126+
expect(codeNumber.attributes('data-line-number')).toBe(`${index + 1}`);
127+
128+
const codeLine = codeLineContainer.find('.code-line');
129+
expect(codeLine.text()).toBe(line);
130+
131+
expect(codeLineContainer.classes('user-highlighted')).toBe(shouldBeHighlighted);
132+
});
133+
});
134+
135+
it('strikes through the correct lines from strikethroughLines', async () => {
136+
const content = ['a', 'b', 'c', 'd', 'e'];
137+
const strikethroughLines = [1, 3];
138+
139+
const wrapper = shallowMount(CodeListing, {
140+
propsData: {
141+
content,
142+
strikethroughLines,
143+
showLineNumbers: true,
144+
},
145+
});
146+
147+
await flushPromises();
148+
149+
const pre = wrapper.find('pre');
150+
expect(pre.exists()).toBe(true);
151+
152+
const codeLineContainers = wrapper.findAll('span.code-line-container');
153+
expect(codeLineContainers.length).toBe(content.length);
154+
155+
content.forEach((line, index) => {
156+
const codeLineContainer = codeLineContainers.at(index);
157+
const shouldBeStriked = strikethroughLines.includes(index + 1);
158+
159+
const codeNumber = codeLineContainer.find('.code-number');
160+
161+
expect(codeNumber.attributes('data-line-number')).toBe(`${index + 1}`);
162+
163+
const codeLine = codeLineContainer.find('.code-line');
164+
expect(codeLine.text()).toBe(line);
165+
166+
expect(codeLineContainer.classes('user-strikethrough')).toBe(shouldBeStriked);
167+
});
168+
});
169+
100170
it('syntax highlights code for Swift', async () => {
101171
const wrapper = shallowMount(CodeListing, {
102172
propsData: {

0 commit comments

Comments
 (0)