Updated to only add numbering to slugified heading anchors when absolutely neccessary
This commit is contained in:
@ -64,14 +64,16 @@ class Contents extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { editor } = this.props;
|
||||||
|
|
||||||
// If there are one or less headings in the document no need for a minimap
|
// If there are one or less headings in the document no need for a minimap
|
||||||
if (this.headings.size <= 1) return null;
|
if (this.headings.size <= 1) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<Sections>
|
<Sections>
|
||||||
{this.headings.map((heading, index) => {
|
{this.headings.map(heading => {
|
||||||
const slug = headingToSlug(heading, index);
|
const slug = headingToSlug(editor.value.document, heading);
|
||||||
const active = this.activeHeading === slug;
|
const active = this.activeHeading === slug;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Document, Block } from 'slate';
|
import { Document } from 'slate';
|
||||||
import type { SlateNodeProps } from '../types';
|
import type { SlateNodeProps } from '../types';
|
||||||
import { List } from 'immutable';
|
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import headingToSlug from '../headingToSlug';
|
import headingToSlug from '../headingToSlug';
|
||||||
import Placeholder from './Placeholder';
|
import Placeholder from './Placeholder';
|
||||||
@ -13,15 +12,6 @@ type Props = SlateNodeProps & {
|
|||||||
placeholder: string,
|
placeholder: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
function indexInDocument(document, heading) {
|
|
||||||
const headings = document.nodes.filter((node: Block) => {
|
|
||||||
if (!node.text) return false;
|
|
||||||
return node.type.match(/^heading/);
|
|
||||||
});
|
|
||||||
|
|
||||||
return headings.indexOf(heading);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Heading(props: Props) {
|
function Heading(props: Props) {
|
||||||
const {
|
const {
|
||||||
parent,
|
parent,
|
||||||
@ -37,10 +27,7 @@ function Heading(props: Props) {
|
|||||||
const parentIsDocument = parent instanceof Document;
|
const parentIsDocument = parent instanceof Document;
|
||||||
const firstHeading = parentIsDocument && parent.nodes.first() === node;
|
const firstHeading = parentIsDocument && parent.nodes.first() === node;
|
||||||
const showPlaceholder = placeholder && firstHeading && !node.text;
|
const showPlaceholder = placeholder && firstHeading && !node.text;
|
||||||
const slugish = headingToSlug(
|
const slugish = headingToSlug(editor.value.document, node);
|
||||||
node,
|
|
||||||
indexInDocument(editor.value.document, node)
|
|
||||||
);
|
|
||||||
const showHash = readOnly && !!slugish;
|
const showHash = readOnly && !!slugish;
|
||||||
const Component = component;
|
const Component = component;
|
||||||
const emoji = editor.props.emoji || '';
|
const emoji = editor.props.emoji || '';
|
||||||
|
@ -1,10 +1,25 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import { escape } from 'lodash';
|
import { escape } from 'lodash';
|
||||||
import { Node } from 'slate';
|
import { Document, Block, Node } from 'slate';
|
||||||
import slug from 'slug';
|
import slug from 'slug';
|
||||||
|
|
||||||
export default function headingToSlug(node: Node, index: number = 0) {
|
// finds the index of this heading in the document compared to other headings
|
||||||
const slugified = escape(slug(node.text));
|
// with the same slugified text
|
||||||
if (index === 0) return slugified;
|
function indexOfType(document, heading) {
|
||||||
return `${index}-${slugified}`;
|
const slugified = escape(slug(heading.text));
|
||||||
|
const headings = document.nodes.filter((node: Block) => {
|
||||||
|
if (!node.text) return false;
|
||||||
|
return node.type.match(/^heading/) && slugified === escape(slug(node.text));
|
||||||
|
});
|
||||||
|
|
||||||
|
return headings.indexOf(heading);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculates a unique slug for this heading based on it's text and position
|
||||||
|
// in the document that is as stable as possible
|
||||||
|
export default function headingToSlug(document: Document, node: Node) {
|
||||||
|
const slugified = escape(slug(node.text));
|
||||||
|
const index = indexOfType(document, node);
|
||||||
|
if (index === 0) return slugified;
|
||||||
|
return `${slugified}-${index}`;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user