Skip to content

Commit

Permalink
Linked headlines (#3540)
Browse files Browse the repository at this point in the history
Co-authored-by: Alin Voinea <contact@avoinea.com>
Co-authored-by: nileshgulia1 <nileshgulia@gmail.com>
Co-authored-by: Timo Stollenwerk <tisto@users.noreply.github.com>
  • Loading branch information
4 people authored Jun 23, 2023
1 parent 37fce92 commit e2ed2fc
Show file tree
Hide file tree
Showing 38 changed files with 447 additions and 58 deletions.
71 changes: 71 additions & 0 deletions cypress/tests/core/blocks/block-anchors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { slateBeforeEach } from '../../../support/volto-slate';

describe('Block Tests: Anchors', () => {
beforeEach(slateBeforeEach);

it('Add Block: Links', () => {
// Change page title
cy.clearSlateTitle();
cy.getSlateTitle().type('Slate Heading Anchors');
cy.getSlate().click();

// Add TOC block
cy.get('.ui.basic.icon.button.block-add-button').first().click();
cy.get(".blocks-chooser .ui.form .field.searchbox input[type='text']").type(
'table of contents',
);
cy.get('.button.toc').click();

// Save page
cy.get('#toolbar-save').click();
cy.url().should('eq', Cypress.config().baseUrl + '/my-page');
cy.get('h1.documentFirstHeading')
.trigger('mouseover', { eventConstructor: 'MouseEvent' })
.children()
.should('have.length', 1);
});

it('Add Block: add content to TOC', () => {
// Change page title
cy.clearSlateTitle();
cy.getSlateTitle().type('Slate Heading Anchors');
cy.getSlate().click();

// Add TOC block
cy.get('.ui.basic.icon.button.block-add-button').first().click();
cy.get(".blocks-chooser .ui.form .field.searchbox input[type='text']").type(
'table of contents',
);
cy.get('.button.toc').click();

// Add headings
cy.get('.ui.drag.block.inner.slate').click().type('Title 1').click();
cy.get('.ui.drag.block.inner.slate span span span').setSelection('Title 1');
cy.get('.slate-inline-toolbar .button-wrapper a[title="Title"]').click({
force: true,
});
cy.get('.ui.drag.block.inner.slate').click().type('{enter}');

cy.get('.ui.drag.block.inner.slate').eq(1).click().type('Title 2').click();
cy.get('.ui.drag.block.inner.slate span span span')
.eq(1)
.setSelection('Title 2');
cy.get('.slate-inline-toolbar .button-wrapper a[title="Title"]').click({
force: true,
});
cy.get('.ui.drag.block.inner.slate').eq(1).click().type('{enter}');

// Save page
cy.get('#toolbar-save').click();
cy.url().should('eq', Cypress.config().baseUrl + '/my-page');

// Check if the page contains the TOC and scrolls to each entry on click
cy.contains('Slate Heading Anchors');
cy.get('h2[id="title-1"]').contains('Title 1');
cy.get('h2[id="title-2"]').contains('Title 2');
cy.get('a[href="#title-1"]').click();
cy.get('h2[id="title-1"]').scrollIntoView().should('be.visible');
cy.get('a[href="#title-2"]').click();
cy.get('h2[id="title-2"]').scrollIntoView().should('be.visible');
});
});
4 changes: 2 additions & 2 deletions cypress/tests/core/guillotina/blocks-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('Text Block Tests', () => {

// then the page view should contain a link
cy.contains('Colorless green ideas sleep furiously.');
cy.get('#page-document a')
cy.get('#page-document p a')
.should('have.attr', 'href')
.and('include', 'https://google.com');
});
Expand Down Expand Up @@ -81,7 +81,7 @@ describe('Text Block Tests', () => {

// then the page view should contain a mailto link
cy.contains('Colorless green ideas sleep furiously.');
cy.get('#page-document a')
cy.get('#page-document p a')
.should('have.attr', 'href')
.and('include', 'mailto:hello@example.com');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ describe('Block Tests: Basic text format', () => {
cy.toolbarSave();

// then the page view should contain our changes
cy.get('[id="page-document"] h2').children().should('have.length', 0);
cy.get('[id="page-document"] h2').children().should('have.length', 1);
cy.get('[id="page-document"] h2').contains('Colorless');
});

Expand Down Expand Up @@ -177,7 +177,7 @@ describe('Block Tests: Basic text format', () => {
cy.toolbarSave();

// then the page view should contain our changes
cy.get('[id="page-document"] h3').children().should('have.length', 0);
cy.get('[id="page-document"] h3').children().should('have.length', 1);
cy.get('[id="page-document"] h3').contains('Colorless');
});

Expand Down
4 changes: 2 additions & 2 deletions cypress/tests/guillotina/blocks-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('Text Block Tests', () => {

// then the page view should contain a link
cy.contains('Colorless green ideas sleep furiously.');
cy.get('#page-document a')
cy.get('#page-document p a')
.should('have.attr', 'href')
.and('include', 'https://google.com');
});
Expand Down Expand Up @@ -81,7 +81,7 @@ describe('Text Block Tests', () => {

// then the page view should contain a mailto link
cy.contains('Colorless green ideas sleep furiously.');
cy.get('#page-document a')
cy.get('#page-document p a')
.should('have.attr', 'href')
.and('include', 'mailto:hello@example.com');
});
Expand Down
13 changes: 13 additions & 0 deletions docs/source/configuration/volto-slate/configuration-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,19 @@ They are not persisted in the final value, so they are useful, for example, to h
slate.runtimeDecorators = [([node, path], ranges) => ranges];
```

(editor-configuration-slate-useLinkedHeadings-label)=

## `slate.useLinkedHeadings`

The setting `slate.useLinkedHeadings` controls whether `volto-slate` creates anchors for headings, such as `h1` and `h2`, in the editor.

The default setting is `true`.

You can opt out of this feature by setting its value to `false`.

```js
slate.useLinkedHeadings = false
```

(editor-configuration-blocks-initialBlocksFocus-label)=

Expand Down
5 changes: 5 additions & 0 deletions locales/ca/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1903,6 +1903,11 @@ msgstr ""
msgid "Link"
msgstr "Enllaç"

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/de/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1900,6 +1900,11 @@ msgstr ""
msgid "Link"
msgstr "Link"

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/en/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1894,6 +1894,11 @@ msgstr ""
msgid "Link"
msgstr ""

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/es/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1905,6 +1905,11 @@ msgstr "Menos filtros"
msgid "Link"
msgstr "Enlace"

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/eu/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1901,6 +1901,11 @@ msgstr ""
msgid "Link"
msgstr "Esteka"

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/fi/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1905,6 +1905,11 @@ msgstr ""
msgid "Link"
msgstr "Linkki"

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/fr/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1911,6 +1911,11 @@ msgstr ""
msgid "Link"
msgstr "Lien"

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/it/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1894,6 +1894,11 @@ msgstr ""
msgid "Link"
msgstr "Link"

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/ja/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,11 @@ msgstr ""
msgid "Link"
msgstr "リンク"

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/nl/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1913,6 +1913,11 @@ msgstr ""
msgid "Link"
msgstr ""

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/pt/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,11 @@ msgstr ""
msgid "Link"
msgstr ""

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/pt_BR/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1904,6 +1904,11 @@ msgstr "Menos filtros"
msgid "Link"
msgstr "Link"

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/ro/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1894,6 +1894,11 @@ msgstr ""
msgid "Link"
msgstr "Legătură"

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/volto.pot
Original file line number Diff line number Diff line change
Expand Up @@ -1896,6 +1896,11 @@ msgstr ""
msgid "Link"
msgstr ""

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
5 changes: 5 additions & 0 deletions locales/zh_CN/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -1900,6 +1900,11 @@ msgstr ""
msgid "Link"
msgstr "链接"

#: helpers/MessageLabels/MessageLabels
# defaultMessage: Link copied to clipboard
msgid "Link copied to clipboard"
msgstr ""

#: components/manage/Blocks/HeroImageLeft/schema
#: components/manage/Blocks/Listing/schema
# defaultMessage: Link more
Expand Down
1 change: 1 addition & 0 deletions news/4287.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added slug-based linked headings in `volto-slate`. @tiberiuichim, @nileshgulia1
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@
"eslint-plugin-react-hooks": "4.0.2",
"express": "4.17.3",
"filesize": "6",
"github-slugger": "1.4.0",
"glob": "7.1.6",
"history": "4.10.1",
"hoist-non-react-statics": "3.3.2",
Expand Down
36 changes: 20 additions & 16 deletions packages/volto-slate/src/blocks/Text/TextBlockView.jsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import { serializeNodes } from '@plone/volto-slate/editor/render';
import {
serializeNodes,
serializeNodesToText,
} from '@plone/volto-slate/editor/render';
import config from '@plone/volto/registry';
import { isEqual } from 'lodash';
import Slugger from 'github-slugger';

const TextBlockView = (props) => {
const { id, data, styling = {} } = props;
const { value, override_toc } = data;
const metadata = props.metadata || props.properties;
return serializeNodes(
value,
(node, path) => {
const res = { ...styling };
if (node.type) {
if (
config.settings.slate.topLevelTargetElements.includes(node.type) ||
override_toc
) {
res.id = id;
}
const { topLevelTargetElements } = config.settings.slate;

const getAttributes = (node, path) => {
const res = { ...styling };
if (node.type && isEqual(path, [0])) {
if (topLevelTargetElements.includes(node.type) || override_toc) {
const text = serializeNodesToText(node?.children || []);
const slug = Slugger.slug(text);
res.id = slug || id;
}
return res;
},
{ metadata: metadata },
);
}
return res;
};

return serializeNodes(value, getAttributes, { metadata: metadata });
};

export default TextBlockView;
Loading

0 comments on commit e2ed2fc

Please sign in to comment.