diff --git a/modules/services/osmose.js b/modules/services/osmose.js index 28f253e74..478180af0 100644 --- a/modules/services/osmose.js +++ b/modules/services/osmose.js @@ -3,6 +3,8 @@ import RBush from 'rbush'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { json as d3_json } from 'd3-fetch'; +import marked from 'marked'; + import { currentLocale } from '../util/locale'; import { geoExtent, geoVecAdd } from '../geo'; import { QAItem } from '../osm'; @@ -60,16 +62,6 @@ function preventCoincident(loc) { return loc; } -// Osmose strings can contain markdown formatting -function parseMarkdown(string) { - // URLs - string = string.replace(/\[((?:.|\n)+?)\]\((.+?)\)/g, - '$1'); - - // Code snippets - return string.replace(/`(.+?)`/g, '$1'); -} - export default { title: 'osmose', @@ -182,7 +174,7 @@ export default { issue.elems = data.elems.map(e => e.type.substring(0,1) + e.id); // Some issues have instance specific detail in a subtitle - issue.detail = parseMarkdown(data.subtitle); + issue.detail = marked(data.subtitle); this.replaceItem(issue); }; @@ -235,11 +227,12 @@ export default { // If string exists, value is an object with key 'auto' for string const { title, detail, fix, trap } = cl; + // Osmose titles shouldn't contain markdown let issueStrings = {}; if (title) issueStrings.title = title.auto; - if (detail) issueStrings.detail = parseMarkdown(detail.auto); - if (trap) issueStrings.trap = parseMarkdown(trap.auto); - if (fix) issueStrings.fix = parseMarkdown(fix.auto); + if (detail) issueStrings.detail = marked(detail.auto); + if (trap) issueStrings.trap = marked(trap.auto); + if (fix) issueStrings.fix = marked(fix.auto); _cache.strings[locale][itemType] = issueStrings; }; diff --git a/modules/ui/osmose_details.js b/modules/ui/osmose_details.js index 6cd6568ef..e4ea677ef 100644 --- a/modules/ui/osmose_details.js +++ b/modules/ui/osmose_details.js @@ -50,7 +50,10 @@ export function uiOsmoseDetails(context) { div .append('p') .attr('class', 'qa-details-description-text') - .html(d => issueString(d, 'detail')); + .html(d => issueString(d, 'detail')) + .selectAll('a') + .attr('rel', 'noopener') + .attr('target', '_blank'); } // Elements (populated later as data is requested) @@ -74,7 +77,10 @@ export function uiOsmoseDetails(context) { div .append('p') - .html(d => issueString(d, 'fix')); + .html(d => issueString(d, 'fix')) + .selectAll('a') + .attr('rel', 'noopener') + .attr('target', '_blank'); } // Common Pitfalls (musn't exist for every issue type) @@ -89,7 +95,10 @@ export function uiOsmoseDetails(context) { div .append('p') - .html(d => issueString(d, 'trap')); + .html(d => issueString(d, 'trap')) + .selectAll('a') + .attr('rel', 'noopener') + .attr('target', '_blank'); } // Save current item to check if UI changed by time request resolves @@ -113,7 +122,10 @@ export function uiOsmoseDetails(context) { detailsDiv .append('p') - .html(d => d.detail); + .html(d => d.detail) + .selectAll('a') + .attr('rel', 'noopener') + .attr('target', '_blank'); } // Create list of linked issue elements