diff --git a/src/plugin/plugin.ts b/src/plugin/plugin.ts index 2d04d13..f3a60a4 100644 --- a/src/plugin/plugin.ts +++ b/src/plugin/plugin.ts @@ -20,11 +20,11 @@ export const cutPlugin: MarkdownIt.PluginSimple = (md) => { continue; } - const newOpenToken = new state.Token(TokenType.CutOpen, 'div', 1); + const newOpenToken = new state.Token(TokenType.CutOpen, 'details', 1); newOpenToken.attrSet('class', ClassNames.Cut); newOpenToken.map = tokens[i].map; - const titleOpen = new state.Token(TokenType.TitleOpen, 'div', 1); + const titleOpen = new state.Token(TokenType.TitleOpen, 'summary', 1); titleOpen.attrSet('class', ClassNames.Title); const titleInline = state.md.parseInline( @@ -32,7 +32,7 @@ export const cutPlugin: MarkdownIt.PluginSimple = (md) => { state.env, )[0]; - const titleClose = new state.Token(TokenType.TitleClose, 'div', -1); + const titleClose = new state.Token(TokenType.TitleClose, 'summary', -1); const contentOpen = new state.Token(TokenType.ContentOpen, 'div', 1); contentOpen.attrSet('class', ClassNames.Content); @@ -46,7 +46,7 @@ export const cutPlugin: MarkdownIt.PluginSimple = (md) => { const contentClose = new state.Token(TokenType.ContentClose, 'div', -1); - const newCloseToken = new state.Token(TokenType.CutClose, 'div', -1); + const newCloseToken = new state.Token(TokenType.CutClose, 'details', -1); newCloseToken.map = tokens[closeTokenIdx].map; const insideTokens = [ diff --git a/src/runtime/styles/cut.scss b/src/runtime/styles/cut.scss index a503b05..60e9277 100644 --- a/src/runtime/styles/cut.scss +++ b/src/runtime/styles/cut.scss @@ -4,11 +4,20 @@ margin-bottom: 15px; &-title { + list-style: none; cursor: pointer; position: relative; user-select: none; padding: 5px 0 5px 30px; + &::-webkit-details-marker { + display: none; + } + + &:focus { + outline-color: $accentColor; + } + &:before { content: ''; z-index: 1; @@ -24,17 +33,10 @@ } &-content { - display: none; - overflow: hidden; - transition: height 0.3s ease-in-out; + padding: 5px 0 15px 30px; } &.open { - > #{$class}-content { - display: revert; - padding: 5px 0 15px 30px; - } - > #{$class}-title:before { transform: translateY(-50%); } diff --git a/tests/plugin.test.ts b/tests/plugin.test.ts index 7ac01b0..4d1420e 100644 --- a/tests/plugin.test.ts +++ b/tests/plugin.test.ts @@ -3,9 +3,7 @@ import transform from '@diplodoc/transform'; import * as cutExtension from '../src/plugin'; const transformYfm = (text: string, opts?: cutExtension.TransformOptions) => { - const { - result, - } = transform(text, { + const {result} = transform(text, { plugins: [cutExtension.transform({bundle: false, ...opts})], }); return result; @@ -18,9 +16,10 @@ describe('Cut extension - plugin', () => { '{% cut "Cut title" %}\n' + '\n' + 'Cut content\n' + '\n' + '{% endcut %}', ).html.replace(/(\r\n|\n|\r)/gm, ''), ).toBe( - '
Cut title
' + - '

Cut content

' + - '
', + '
' + + 'Cut title' + + '

Cut content

' + + '
', ); }); @@ -36,9 +35,12 @@ describe('Cut extension - plugin', () => { '{% endcut %}', ).html.replace(/(\r\n|\n|\r)/gm, ''), ).toBe( - '
Cut title
' + - '
Code
' + - '
', + '
' + + 'Cut title' + + '
' + + '
Code
' + + '
' + + '
', ); }); @@ -58,12 +60,15 @@ describe('Cut extension - plugin', () => { '{% endcut %}', ).html.replace(/(\r\n|\n|\r)/gm, ''), ).toBe( - '
Cut title 1
' + - '

Cut content 1

' + - '
' + - '
Cut title 2
' + - '

Cut content 2

' + - '
', + '
' + + 'Cut title 1' + + '

Cut content 1

' + + '
' + + '
' + + 'Cut title 2' + + '
' + + '

Cut content 2

' + + '
', ); }); @@ -83,11 +88,12 @@ describe('Cut extension - plugin', () => { '{% endcut %}', ).html.replace(/(\r\n|\n|\r)/gm, ''), ).toBe( - '
Outer title
' + - '

Outer content

' + - '
Inner title
' + - '

Inner content

' + - '
', + '
' + + 'Outer title
' + + '

Outer content

' + + 'Inner title' + + '

Inner content

' + + '
', ); }); @@ -101,10 +107,11 @@ describe('Cut extension - plugin', () => { '{% endcut %}', ).html.replace(/(\r\n|\n|\r)/gm, ''), ).toBe( - '
' + - '
Strong cut title
' + - '

Content we want to hide

' + - '
', + '
' + + 'Strong cut title' + + '
' + + '

Content we want to hide

' + + '
', ); }); @@ -120,8 +127,11 @@ describe('Cut extension - plugin', () => { '{% endcut %}', ).html.replace(/(\r\n|\n|\r)/gm, ''), ).toBe( - '', + '', ); }); @@ -147,12 +157,16 @@ describe('Cut extension - plugin', () => { '{% endcut %}', ).html.replace(/(\r\n|\n|\r)/gm, ''), ).toBe( - '', + '', ); }); @@ -163,22 +177,25 @@ describe('Cut extension - plugin', () => { it('should add default assets to meta', () => { const markup = '{% cut "Cut title" %}\n' + '\n' + 'Cut content\n' + '\n' + '{% endcut %}'; - expect( - transformYfm(markup).meta - ).toStrictEqual({ script: ['_assets/cut-extension.js'], style: ['_assets/cut-extension.css'] }); + expect(transformYfm(markup).meta).toStrictEqual({ + script: ['_assets/cut-extension.js'], + style: ['_assets/cut-extension.css'], + }); }); it('should add custom assets to meta', () => { const markup = '{% cut "Cut title" %}\n' + '\n' + 'Cut content\n' + '\n' + '{% endcut %}'; - expect( - transformYfm(markup, {runtime: 'yfm-cut'}).meta - ).toStrictEqual({ script: ['yfm-cut'], style: ['yfm-cut'] }); + expect(transformYfm(markup, {runtime: 'yfm-cut'}).meta).toStrictEqual({ + script: ['yfm-cut'], + style: ['yfm-cut'], + }); }); it('should add custom assets to meta 2', () => { const markup = '{% cut "Cut title" %}\n' + '\n' + 'Cut content\n' + '\n' + '{% endcut %}'; expect( - transformYfm(markup, {runtime: {script: 'yfm-cut.script', style: 'yfm-cut.style'}}).meta - ).toStrictEqual({ script: ['yfm-cut.script'], style: ['yfm-cut.style'] }); + transformYfm(markup, {runtime: {script: 'yfm-cut.script', style: 'yfm-cut.style'}}) + .meta, + ).toStrictEqual({script: ['yfm-cut.script'], style: ['yfm-cut.style']}); }); });