Updated to only add numbering to slugified heading anchors when absolutely neccessary

This commit is contained in:
Tom Moor
2018-01-27 11:45:46 -08:00
parent 7647d23804
commit edcb92d223
3 changed files with 26 additions and 22 deletions

View File

@ -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 (

View File

@ -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 || '';

View File

@ -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}`;
} }