Skip to content

Commit 55d971a

Browse files
[settings-view] Fix rendering of setting descriptions with line breaks… (#1620)
…so that each section is wrapped in a P tag when appropriate.
1 parent 3ebeca8 commit 55d971a

4 files changed

Lines changed: 71 additions & 5 deletions

File tree

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
module.exports = {
3-
getSettingDescription (keyPath) {
3+
getSettingDescription(keyPath) {
44
const schema = atom.config.getSchema(keyPath)
55
let description = ''
66
if (schema && schema.description) {
@@ -11,13 +11,20 @@ module.exports = {
1111
if (atom.i18n.isAutoTranslateLabel(description)) {
1212
description = atom.i18n.translateLabel(description);
1313
}
14-
15-
return atom.ui.markdown.render(
14+
15+
let contents = atom.ui.markdown.render(
1616
description,
1717
{
1818
useTaskCheckbox: false,
1919
disableMode: "strict",
2020
}
21-
).replace(/<p>(.*)<\/p>/, "$1").trim();
21+
)
22+
23+
// If the setting has no internal paragraph breaks, strip it of its
24+
// surrounding `p` tag. Otherwise keep the `p`.
25+
if ((contents.match(/<p>/g)?.length ?? 0) <= 1) {
26+
contents = contents.replace(/<p>(.*)<\/p>/, "$1").trim()
27+
}
28+
return contents
2229
}
2330
}

packages/settings-view/lib/settings-panel.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ function elementForOptions (namespace, name, value, {radio = false}) {
490490

491491
const label = document.createElement('label')
492492
label.classList.add('control-label')
493+
label.dataset.settingKey = keyPath
493494

494495
const titleDiv = document.createElement('div')
495496
titleDiv.classList.add('setting-title')
@@ -515,6 +516,7 @@ function elementForCheckbox (namespace, name, value) {
515516

516517
const label = document.createElement('label')
517518
label.for = keyPath
519+
label.dataset.settingKey = keyPath
518520

519521
const input = document.createElement('input')
520522
input.id = keyPath
@@ -544,6 +546,7 @@ function elementForColor (namespace, name, value) {
544546

545547
const label = document.createElement('label')
546548
label.for = keyPath
549+
label.dataset.settingKey = keyPath
547550

548551
const input = document.createElement('input')
549552
input.id = keyPath
@@ -572,6 +575,7 @@ function elementForEditor (namespace, name, value) {
572575

573576
const label = document.createElement('label')
574577
label.classList.add('control-label')
578+
label.dataset.settingKey = keyPath
575579

576580
const titleDiv = document.createElement('div')
577581
titleDiv.classList.add('setting-title')
@@ -607,6 +611,7 @@ function elementForArray (namespace, name, value) {
607611

608612
const label = document.createElement('label')
609613
label.classList.add('control-label')
614+
label.dataset.settingKey = keyPath
610615

611616
const titleDiv = document.createElement('div')
612617
titleDiv.classList.add('setting-title')

packages/settings-view/spec/.eslintrc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ module.exports = {
55
node: true
66
},
77
globals: {
8-
waitsForPromise: true
8+
waitsForPromise: true,
9+
advanceClock: true
910
},
1011
rules: {
1112
"node/no-missing-require": "off",

packages/settings-view/spec/settings-panel-spec.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,4 +465,57 @@ describe("SettingsPanel", () => {
465465
});
466466
});
467467
});
468+
469+
describe('settings rendering', () => {
470+
beforeEach(() => {
471+
const config = {
472+
type: 'object',
473+
properties: {
474+
troz: {
475+
title: 'troz',
476+
// Testing paragraph breaks inside a description.
477+
description: 'The troz setting.\n\nIgnored unless `zort` is also `true`.',
478+
type: 'string',
479+
default: 'troz',
480+
},
481+
minMax: {
482+
name: 'minMax',
483+
title: 'Min max',
484+
description: 'The minMax setting',
485+
type: 'integer',
486+
default: 10,
487+
minimum: 1,
488+
maximum: 100
489+
},
490+
commaValueArray: {
491+
name: 'commaValueArray',
492+
title: 'Comma value in array',
493+
description: 'An array with a comma value',
494+
type: 'array',
495+
default: []
496+
}
497+
}
498+
};
499+
500+
atom.config.setSchema('foo', config);
501+
settingsPanel = new SettingsPanel({namespace: 'foo', includeTitle: false});
502+
});
503+
504+
it('renders a setting description as Markdown', () => {
505+
// A setting with internal paragraph breaks should end up with two P
506+
// elements…
507+
const trozDescription = settingsPanel.element.querySelector(
508+
`label[data-setting-key="foo.troz"] > .setting-description`
509+
);
510+
expect(trozDescription.querySelectorAll('p').length).toBe(2);
511+
512+
// …but a setting without any paragraph breaks should have its outer P
513+
// element stripped.
514+
const minMaxDescription = settingsPanel.element.querySelector(
515+
`label[data-setting-key="foo.minMax"] > .setting-description`
516+
);
517+
expect(minMaxDescription.querySelectorAll('p').length).toBe(0);
518+
});
519+
});
520+
468521
});

0 commit comments

Comments
 (0)