Use prefix for TableOfContents filter hrefs

TableOfContents filter generates hrefs for each header in markdown,
if the header text consists from digits and redacted symbols only,
e.g. "123" or "1.0 then the auto-generated href has the same format
as issue references.

If the generated id contains only digits, then 'anchor-' prefix is
prepended to the id.

Closes #38473
This commit is contained in:
Jan Provaznik 2017-12-08 10:50:22 +01:00
parent 29e39e55c3
commit 3e83d9f73a
4 changed files with 23 additions and 0 deletions

View file

@ -0,0 +1,6 @@
---
title: Fix false positive issue references in merge requests caused by header anchor
links.
merge_request:
author:
type: fixed

View file

@ -32,6 +32,7 @@ module Banzai
.gsub(PUNCTUATION_REGEXP, '') # remove punctuation .gsub(PUNCTUATION_REGEXP, '') # remove punctuation
.tr(' ', '-') # replace spaces with dash .tr(' ', '-') # replace spaces with dash
.squeeze('-') # replace multiple dashes with one .squeeze('-') # replace multiple dashes with one
.gsub(/\A(\d+)\z/, 'anchor-\1') # digits-only hrefs conflict with issue refs
uniq = headers[id] > 0 ? "-#{headers[id]}" : '' uniq = headers[id] > 0 ? "-#{headers[id]}" : ''
headers[id] += 1 headers[id] += 1

View file

@ -65,6 +65,13 @@ describe Banzai::Filter::TableOfContentsFilter do
expect(doc.css('h2 a').first.attr('href')).to eq '#one-1' expect(doc.css('h2 a').first.attr('href')).to eq '#one-1'
end end
it 'prepends a prefix to digits-only ids' do
doc = filter(header(1, "123") + header(2, "1.0"))
expect(doc.css('h1 a').first.attr('href')).to eq '#anchor-123'
expect(doc.css('h2 a').first.attr('href')).to eq '#anchor-10'
end
it 'supports Unicode' do it 'supports Unicode' do
doc = filter(header(1, '한글')) doc = filter(header(1, '한글'))
expect(doc.css('h1 a').first.attr('id')).to eq 'user-content-한글' expect(doc.css('h1 a').first.attr('id')).to eq 'user-content-한글'

View file

@ -115,6 +115,15 @@ describe Gitlab::ReferenceExtractor do
end end
end end
it 'does not include anchors from table of contents in issue references' do
issue1 = create(:issue, project: project)
issue2 = create(:issue, project: project)
subject.analyze("not real issue <h4>#{issue1.iid}</h4>, real issue #{issue2.to_reference}")
expect(subject.issues).to match_array([issue2])
end
it 'accesses valid issue objects' do it 'accesses valid issue objects' do
@i0 = create(:issue, project: project) @i0 = create(:issue, project: project)
@i1 = create(:issue, project: project) @i1 = create(:issue, project: project)