From af59ed027df3fec6caba85f48247a148b5b57225 Mon Sep 17 00:00:00 2001 From: Jay Swain <jswain@gitlab.com> Date: Mon, 24 May 2021 17:49:42 -0700 Subject: [PATCH] What's New content link opens in new tab What's new items have body content which is written in markdown. This commit makes each link within the body content to open in a new tab. part of: https://gitlab.com/gitlab-org/growth/engineering/-/issues/5434 Changelog: changed --- .../javascripts/whats_new/components/feature.vue | 6 +++++- app/models/release_highlight.rb | 2 +- spec/fixtures/whats_new/20201225_01_05.yml | 2 +- spec/frontend/whats_new/components/feature_spec.js | 12 +++++++++++- spec/models/release_highlight_spec.rb | 6 +++--- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/whats_new/components/feature.vue b/app/assets/javascripts/whats_new/components/feature.vue index 5444e77a4d2cd..11096b0803232 100644 --- a/app/assets/javascripts/whats_new/components/feature.vue +++ b/app/assets/javascripts/whats_new/components/feature.vue @@ -30,6 +30,7 @@ export default { return dateInWords(date); }, }, + safeHtmlConfig: { ADD_ATTR: ['target'] }, }; </script> @@ -71,7 +72,10 @@ export default { <gl-icon name="license" />{{ packageName }} </gl-badge> </div> - <div v-safe-html="feature.body" class="gl-pt-3 gl-line-height-20"></div> + <div + v-safe-html:[$options.safeHtmlConfig]="feature.body" + class="gl-pt-3 gl-line-height-20" + ></div> <gl-button :href="feature.url" target="_blank" diff --git a/app/models/release_highlight.rb b/app/models/release_highlight.rb index 9c30d0611e6d5..84e0a43670b78 100644 --- a/app/models/release_highlight.rb +++ b/app/models/release_highlight.rb @@ -33,7 +33,7 @@ def self.load_items(page:) next unless include_item?(item) begin - item.tap {|i| i['body'] = Kramdown::Document.new(i['body']).to_html } + item.tap {|i| i['body'] = Banzai.render(i['body'], { project: nil }) } rescue StandardError => e Gitlab::ErrorTracking.track_exception(e, file_path: file_path) diff --git a/spec/fixtures/whats_new/20201225_01_05.yml b/spec/fixtures/whats_new/20201225_01_05.yml index 27c8f989b085e..d707502af54df 100644 --- a/spec/fixtures/whats_new/20201225_01_05.yml +++ b/spec/fixtures/whats_new/20201225_01_05.yml @@ -1,7 +1,7 @@ --- - title: bright and sunshinin' day body: | - ## bright and sunshinin' day + bright and sunshinin' [day](https://en.wikipedia.org/wiki/Day) self-managed: true gitlab-com: false packages: ["Premium", "Ultimate"] diff --git a/spec/frontend/whats_new/components/feature_spec.js b/spec/frontend/whats_new/components/feature_spec.js index 9e9cb59c0d687..8f4b4b08f5067 100644 --- a/spec/frontend/whats_new/components/feature_spec.js +++ b/spec/frontend/whats_new/components/feature_spec.js @@ -8,7 +8,7 @@ describe("What's new single feature", () => { const exampleFeature = { title: 'Compliance pipeline configurations', body: - '<p>We are thrilled to announce that it is now possible to define enforceable pipelines that will run for any project assigned a corresponding compliance framework.</p>', + '<p data-testid="body-content">We are thrilled to announce that it is now possible to define enforceable pipelines that will run for any project assigned a corresponding <a href="https://en.wikipedia.org/wiki/Compliance_(psychology)" target="_blank" rel="noopener noreferrer" onload="alert(xss)">compliance</a> framework.</p>', stage: 'Manage', 'self-managed': true, 'gitlab-com': true, @@ -20,6 +20,7 @@ describe("What's new single feature", () => { }; const findReleaseDate = () => wrapper.find('[data-testid="release-date"]'); + const findBodyAnchor = () => wrapper.find('[data-testid="body-content"] a'); const createWrapper = ({ feature } = {}) => { wrapper = shallowMount(Feature, { @@ -43,4 +44,13 @@ describe("What's new single feature", () => { expect(findReleaseDate().exists()).toBe(false); }); }); + + it('safe-html config allows target attribute on elements', () => { + createWrapper({ feature: exampleFeature }); + expect(findBodyAnchor().attributes()).toEqual({ + href: expect.any(String), + rel: 'noopener noreferrer', + target: '_blank', + }); + }); }); diff --git a/spec/models/release_highlight_spec.rb b/spec/models/release_highlight_spec.rb index b4dff4c33ff61..a5441e2f47bd4 100644 --- a/spec/models/release_highlight_spec.rb +++ b/spec/models/release_highlight_spec.rb @@ -67,12 +67,12 @@ expect(subject[:next_page]).to eq(2) end - it 'parses the body as markdown and returns html' do - expect(subject[:items].first['body']).to match("<h2 id=\"bright-and-sunshinin-day\">bright and sunshinin’ day</h2>") + it 'parses the body as markdown and returns html, and links are target="_blank"' do + expect(subject[:items].first['body']).to match('<p data-sourcepos="1:1-1:62" dir="auto">bright and sunshinin\' <a href="https://en.wikipedia.org/wiki/Day" rel="nofollow noreferrer noopener" target="_blank">day</a></p>') end it 'logs an error if theres an error parsing markdown for an item, and skips it' do - allow(Kramdown::Document).to receive(:new).and_raise + allow(Banzai).to receive(:render).and_raise expect(Gitlab::ErrorTracking).to receive(:track_exception) expect(subject[:items]).to be_empty -- GitLab