mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-12-22 18:21:34 +00:00
refactor(common): extract frontmatter code into commons
Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
parent
a78ac5f097
commit
8bd7fd1be8
26 changed files with 433 additions and 121 deletions
|
@ -40,6 +40,7 @@
|
|||
"dependencies": {
|
||||
"eventemitter2": "6.4.9",
|
||||
"isomorphic-ws": "5.0.0",
|
||||
"reveal.js": "4.4.0",
|
||||
"ws": "8.13.0",
|
||||
"yjs": "13.5.51"
|
||||
},
|
||||
|
|
|
@ -22,4 +22,11 @@ export * from './y-doc-sync/y-doc-sync-adapter.js'
|
|||
|
||||
export { waitForOtherPromisesToFinish } from './utils/wait-for-other-promises-to-finish.js'
|
||||
|
||||
export { RealtimeDoc } from './y-doc-sync/realtime-doc'
|
||||
export { RealtimeDoc } from './y-doc-sync/realtime-doc.js'
|
||||
|
||||
export * from './title-extraction/frontmatter-extractor/extractor.js'
|
||||
export * from './title-extraction/frontmatter-extractor/types.js'
|
||||
export * from './title-extraction/generate-note-title.js'
|
||||
export * from './title-extraction/types/iso6391.js'
|
||||
export * from './title-extraction/types/frontmatter.js'
|
||||
export * from './title-extraction/types/slide-show-options.js'
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { extractFrontmatter } from './extractor'
|
||||
import type { PresentFrontmatterExtractionResult } from './types'
|
||||
import { extractFrontmatter } from './extractor.js'
|
||||
import type { PresentFrontmatterExtractionResult } from './types.js'
|
||||
import { describe, expect, it } from '@jest/globals'
|
||||
|
||||
describe('frontmatter extraction', () => {
|
||||
describe('isPresent property', () => {
|
||||
|
@ -29,7 +30,13 @@ describe('frontmatter extraction', () => {
|
|||
expect(extraction.isPresent).toBe(false)
|
||||
})
|
||||
it('is false when note has no ending marker for frontmatter', () => {
|
||||
const testNote = ['---', 'this is not frontmatter', 'because', 'there is no', 'end marker']
|
||||
const testNote = [
|
||||
'---',
|
||||
'this is not frontmatter',
|
||||
'because',
|
||||
'there is no',
|
||||
'end marker'
|
||||
]
|
||||
const extraction = extractFrontmatter(testNote)
|
||||
expect(extraction.isPresent).toBe(false)
|
||||
})
|
||||
|
@ -58,22 +65,30 @@ describe('frontmatter extraction', () => {
|
|||
describe('lineOffset property', () => {
|
||||
it('is correct for single line frontmatter without content', () => {
|
||||
const testNote = ['---', 'single line frontmatter', '...']
|
||||
const extraction = extractFrontmatter(testNote) as PresentFrontmatterExtractionResult
|
||||
const extraction = extractFrontmatter(
|
||||
testNote
|
||||
) as PresentFrontmatterExtractionResult
|
||||
expect(extraction.lineOffset).toEqual(3)
|
||||
})
|
||||
it('is correct for single line frontmatter with content', () => {
|
||||
const testNote = ['---', 'single line frontmatter', '...', 'content']
|
||||
const extraction = extractFrontmatter(testNote) as PresentFrontmatterExtractionResult
|
||||
const extraction = extractFrontmatter(
|
||||
testNote
|
||||
) as PresentFrontmatterExtractionResult
|
||||
expect(extraction.lineOffset).toEqual(3)
|
||||
})
|
||||
it('is correct for multi-line frontmatter without content', () => {
|
||||
const testNote = ['---', 'abc', '123', 'def', '...']
|
||||
const extraction = extractFrontmatter(testNote) as PresentFrontmatterExtractionResult
|
||||
const extraction = extractFrontmatter(
|
||||
testNote
|
||||
) as PresentFrontmatterExtractionResult
|
||||
expect(extraction.lineOffset).toEqual(5)
|
||||
})
|
||||
it('is correct for multi-line frontmatter with content', () => {
|
||||
const testNote = ['---', 'abc', '123', 'def', '...', 'content']
|
||||
const extraction = extractFrontmatter(testNote) as PresentFrontmatterExtractionResult
|
||||
const extraction = extractFrontmatter(
|
||||
testNote
|
||||
) as PresentFrontmatterExtractionResult
|
||||
expect(extraction.lineOffset).toEqual(5)
|
||||
})
|
||||
})
|
||||
|
@ -81,12 +96,16 @@ describe('frontmatter extraction', () => {
|
|||
describe('rawText property', () => {
|
||||
it('contains single-line frontmatter text', () => {
|
||||
const testNote = ['---', 'single-line', '...', 'content']
|
||||
const extraction = extractFrontmatter(testNote) as PresentFrontmatterExtractionResult
|
||||
const extraction = extractFrontmatter(
|
||||
testNote
|
||||
) as PresentFrontmatterExtractionResult
|
||||
expect(extraction.rawText).toEqual('single-line')
|
||||
})
|
||||
it('contains multi-line frontmatter text', () => {
|
||||
const testNote = ['---', 'multi', 'line', '...', 'content']
|
||||
const extraction = extractFrontmatter(testNote) as PresentFrontmatterExtractionResult
|
||||
const extraction = extractFrontmatter(
|
||||
testNote
|
||||
) as PresentFrontmatterExtractionResult
|
||||
expect(extraction.rawText).toEqual('multi\nline')
|
||||
})
|
||||
})
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { FrontmatterExtractionResult } from './types'
|
||||
import type { FrontmatterExtractionResult } from './types.js'
|
||||
|
||||
const FRONTMATTER_BEGIN_REGEX = /^-{3,}$/
|
||||
const FRONTMATTER_END_REGEX = /^(?:-{3,}|\.{3,})$/
|
||||
|
@ -18,14 +18,19 @@ const FRONTMATTER_END_REGEX = /^(?:-{3,}|\.{3,})$/
|
|||
* { frontmatterLines } if a block was found, this property contains the number of lines to skip from the
|
||||
* given multiline string for retrieving the non-frontmatter content.
|
||||
*/
|
||||
export const extractFrontmatter = (lines: string[]): FrontmatterExtractionResult => {
|
||||
export const extractFrontmatter = (
|
||||
lines: string[]
|
||||
): FrontmatterExtractionResult => {
|
||||
if (lines.length < 2 || !FRONTMATTER_BEGIN_REGEX.test(lines[0])) {
|
||||
return {
|
||||
isPresent: false
|
||||
}
|
||||
}
|
||||
for (let i = 1; i < lines.length; i++) {
|
||||
if (lines[i].length === lines[0].length && FRONTMATTER_END_REGEX.test(lines[i])) {
|
||||
if (
|
||||
lines[i].length === lines[0].length &&
|
||||
FRONTMATTER_END_REGEX.test(lines[i])
|
||||
) {
|
||||
return {
|
||||
isPresent: true,
|
||||
rawText: lines.slice(1, i).join('\n'),
|
|
@ -1,10 +1,12 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export type FrontmatterExtractionResult = PresentFrontmatterExtractionResult | NonPresentFrontmatterExtractionResult
|
||||
export type FrontmatterExtractionResult =
|
||||
| PresentFrontmatterExtractionResult
|
||||
| NonPresentFrontmatterExtractionResult
|
||||
|
||||
export interface PresentFrontmatterExtractionResult {
|
||||
isPresent: true
|
58
commons/src/title-extraction/generate-note-title.spec.ts
Normal file
58
commons/src/title-extraction/generate-note-title.spec.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { generateNoteTitle } from './generate-note-title.js'
|
||||
import { NoteFrontmatter, NoteTextDirection } from './types/frontmatter.js'
|
||||
import { NoteType } from './types/frontmatter.js'
|
||||
import { describe, expect, it } from '@jest/globals'
|
||||
|
||||
const testFrontmatter: NoteFrontmatter = {
|
||||
title: '',
|
||||
description: '',
|
||||
tags: [],
|
||||
robots: '',
|
||||
lang: 'en',
|
||||
dir: NoteTextDirection.LTR,
|
||||
newlinesAreBreaks: true,
|
||||
GA: '',
|
||||
disqus: '',
|
||||
license: '',
|
||||
type: NoteType.DOCUMENT,
|
||||
opengraph: {},
|
||||
slideOptions: {
|
||||
transition: 'zoom',
|
||||
autoSlide: 0,
|
||||
autoSlideStoppable: true,
|
||||
backgroundTransition: 'fade',
|
||||
slideNumber: false
|
||||
}
|
||||
}
|
||||
|
||||
describe('generate note title', () => {
|
||||
it('will choose the frontmatter title first', () => {
|
||||
const actual = generateNoteTitle(
|
||||
{
|
||||
...testFrontmatter,
|
||||
title: 'frontmatter',
|
||||
opengraph: { title: 'opengraph' }
|
||||
},
|
||||
'first-heading'
|
||||
)
|
||||
expect(actual).toEqual('frontmatter')
|
||||
})
|
||||
|
||||
it('will choose the opengraph title second', () => {
|
||||
const actual = generateNoteTitle(
|
||||
{ ...testFrontmatter, opengraph: { title: 'opengraph' } },
|
||||
'first-heading'
|
||||
)
|
||||
expect(actual).toEqual('opengraph')
|
||||
})
|
||||
|
||||
it('will choose the first heading third', () => {
|
||||
const actual = generateNoteTitle({ ...testFrontmatter }, 'first-heading')
|
||||
expect(actual).toEqual('first-heading')
|
||||
})
|
||||
})
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { NoteFrontmatter } from './types/note-details'
|
||||
import type { NoteFrontmatter } from './types/frontmatter.js'
|
||||
|
||||
/**
|
||||
* Generates the note title from the given frontmatter or the first heading in the markdown content.
|
||||
|
@ -12,7 +12,10 @@ import type { NoteFrontmatter } from './types/note-details'
|
|||
* @param firstHeading The first heading in the markdown content
|
||||
* @return The title from the frontmatter or, if no title is present in the frontmatter, the first heading.
|
||||
*/
|
||||
export const generateNoteTitle = (frontmatter: NoteFrontmatter, firstHeading?: string): string => {
|
||||
export const generateNoteTitle = (
|
||||
frontmatter: NoteFrontmatter,
|
||||
firstHeading?: string
|
||||
): string => {
|
||||
if (frontmatter?.title && frontmatter?.title !== '') {
|
||||
return frontmatter.title.trim()
|
||||
} else if (
|
36
commons/src/title-extraction/types/frontmatter.ts
Normal file
36
commons/src/title-extraction/types/frontmatter.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { ISO6391 } from './iso6391.js'
|
||||
import { SlideOptions } from './slide-show-options.js'
|
||||
|
||||
export type Iso6391Language = (typeof ISO6391)[number]
|
||||
|
||||
export type OpenGraph = Record<string, string>
|
||||
|
||||
export enum NoteTextDirection {
|
||||
LTR = 'ltr',
|
||||
RTL = 'rtl'
|
||||
}
|
||||
|
||||
export enum NoteType {
|
||||
DOCUMENT = '',
|
||||
SLIDE = 'slide'
|
||||
}
|
||||
export interface NoteFrontmatter {
|
||||
title: string
|
||||
description: string
|
||||
tags: string[]
|
||||
robots: string
|
||||
lang: Iso6391Language
|
||||
dir: NoteTextDirection
|
||||
newlinesAreBreaks: boolean
|
||||
GA: string
|
||||
disqus: string
|
||||
license: string
|
||||
type: NoteType
|
||||
opengraph: OpenGraph
|
||||
slideOptions: SlideOptions
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
15
commons/src/title-extraction/types/slide-show-options.ts
Normal file
15
commons/src/title-extraction/types/slide-show-options.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { RevealOptions } from 'reveal.js'
|
||||
|
||||
type WantedRevealOptions =
|
||||
| 'autoSlide'
|
||||
| 'autoSlideStoppable'
|
||||
| 'transition'
|
||||
| 'backgroundTransition'
|
||||
| 'slideNumber'
|
||||
|
||||
export type SlideOptions = Required<Pick<RevealOptions, WantedRevealOptions>>
|
|
@ -18,8 +18,9 @@
|
|||
"rootDir": "./src",
|
||||
"allowJs": true,
|
||||
"declarationMap":true,
|
||||
"sourceMap": true
|
||||
"sourceMap": true,
|
||||
"typeRoots": ["./types"]
|
||||
},
|
||||
"include": ["./src"],
|
||||
"include": ["./src", "./types"],
|
||||
"exclude": ["./dist"]
|
||||
}
|
||||
|
|
237
commons/types/reveal.d.ts
vendored
Normal file
237
commons/types/reveal.d.ts
vendored
Normal file
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare module 'reveal.js' {
|
||||
export interface RevealOptions {
|
||||
// Configuration
|
||||
controls?: boolean | undefined
|
||||
progress?: boolean | undefined
|
||||
// https://github.com/hakimel/reveal.js/#slide-number
|
||||
slideNumber?: boolean | string | undefined
|
||||
|
||||
history?: boolean | undefined
|
||||
plugins?: Plugin[] | undefined
|
||||
|
||||
// https://github.com/hakimel/reveal.js/#keyboard-bindings
|
||||
// keyboard?: any
|
||||
overview?: boolean | undefined
|
||||
center?: boolean | undefined
|
||||
touch?: boolean | undefined
|
||||
loop?: boolean | undefined
|
||||
rtl?: boolean | undefined
|
||||
shuffle?: boolean | undefined
|
||||
fragments?: boolean | undefined
|
||||
embedded?: boolean | undefined
|
||||
help?: boolean | undefined
|
||||
showNotes?: boolean | undefined
|
||||
autoSlide?: number | undefined
|
||||
autoSlideStoppable?: boolean | undefined
|
||||
// autoSlideMethod?: any
|
||||
mouseWheel?: boolean | undefined
|
||||
hideAddressBar?: boolean | undefined
|
||||
previewLinks?: boolean | undefined
|
||||
transition?: string | undefined
|
||||
transitionSpeed?: string | undefined
|
||||
backgroundTransition?: string | undefined
|
||||
viewDistance?: number | undefined
|
||||
|
||||
// https://github.com/hakimel/reveal.js/#parallax-background
|
||||
// Parallax background image
|
||||
parallaxBackgroundImage?: string | undefined
|
||||
|
||||
// Parallax background size
|
||||
parallaxBackgroundSize?: string | undefined // CSS syntax, e.g. "2100px 900px" - currently only pixels are supported (don't use % or auto)
|
||||
|
||||
// Number of pixels to move the parallax background per slide
|
||||
// - Calculated automatically unless specified
|
||||
// - Set to 0 to disable movement along an axis
|
||||
parallaxBackgroundHorizontal?: number | undefined
|
||||
parallaxBackgroundVertical?: number | undefined
|
||||
|
||||
rollingLinks?: boolean | undefined
|
||||
theme?: string | undefined
|
||||
|
||||
// Presentation Size
|
||||
// https://github.com/hakimel/reveal.js/#presentation-size
|
||||
width?: number | string | undefined
|
||||
height?: number | string | undefined
|
||||
margin?: number | string | undefined
|
||||
minScale?: number | string | undefined
|
||||
maxScale?: number | string | undefined
|
||||
|
||||
// Dependencies
|
||||
// https://github.com/hakimel/reveal.js/#dependencies
|
||||
dependencies?: RevealDependency[] | undefined
|
||||
|
||||
// Exposes the reveal.js API through window.postMessage
|
||||
postMessage?: boolean | undefined
|
||||
|
||||
// Dispatches all reveal.js events to the parent window through postMessage
|
||||
postMessageEvents?: boolean | undefined
|
||||
|
||||
// https://github.com/hakimel/reveal.js/#multiplexing
|
||||
multiplex?: MultiplexConfig | undefined
|
||||
|
||||
// https://github.com/hakimel/reveal.js/#mathjax
|
||||
math?: MathConfig | undefined
|
||||
}
|
||||
|
||||
// https://github.com/hakimel/reveal.js/#slide-changed-event
|
||||
export interface SlideEvent {
|
||||
previousSlide?: Element | undefined
|
||||
currentSlide: Element
|
||||
indexh: number
|
||||
indexv?: number | undefined
|
||||
}
|
||||
|
||||
// https://github.com/hakimel/reveal.js/#fragment-events
|
||||
export interface FragmentEvent {
|
||||
fragment: Element
|
||||
}
|
||||
|
||||
// https://github.com/hakimel/reveal.js/#multiplexing
|
||||
export interface MultiplexConfig {
|
||||
// Obtained from the socket.io server. Gives this (the master) control of the presentation
|
||||
secret?: string | undefined
|
||||
// Obtained from the socket.io server
|
||||
id: string
|
||||
|
||||
// Location of socket.io server
|
||||
url: string
|
||||
}
|
||||
|
||||
// https://github.com/hakimel/reveal.js/#mathjax
|
||||
export interface MathConfig {
|
||||
// Obtained from the socket.io server. Gives this (the master) control of the presentation
|
||||
mathjax: string
|
||||
// Obtained from the socket.io server
|
||||
config: string
|
||||
}
|
||||
|
||||
// https://github.com/hakimel/reveal.js/#dependencies
|
||||
export interface RevealDependency {
|
||||
src: string
|
||||
condition?: (() => boolean) | undefined
|
||||
async?: boolean | undefined
|
||||
callback?: (() => void) | undefined
|
||||
}
|
||||
|
||||
export interface Plugin {
|
||||
id: string
|
||||
|
||||
init(deck: RevealStatic): void | Promise<void>
|
||||
}
|
||||
|
||||
export default class Reveal {
|
||||
constructor(options: RevealOptions)
|
||||
|
||||
initialize: (options?: { url?: string }) => Promise<void>
|
||||
|
||||
public configure: (diff: RevealOptions) => void
|
||||
|
||||
public destroy: () => void
|
||||
|
||||
// Navigation
|
||||
public slide(indexh: number, indexv?: number, f?: number, o?: number): void
|
||||
|
||||
public left(): void
|
||||
|
||||
public right(): void
|
||||
|
||||
public up(): void
|
||||
|
||||
public down(): void
|
||||
|
||||
public prev(): void
|
||||
|
||||
public next(): void
|
||||
|
||||
public prevFragment(): boolean
|
||||
|
||||
public nextFragment(): boolean
|
||||
|
||||
// Randomize the order of slides
|
||||
public shuffle(): void
|
||||
|
||||
// Toggle presentation states
|
||||
public toggleOverview(override?: boolean): void
|
||||
|
||||
public togglePause(override?: boolean): void
|
||||
|
||||
public toggleAutoSlide(override?: boolean): void
|
||||
|
||||
// Retrieves the previous and current slide elements
|
||||
public getPreviousSlide(): Element
|
||||
|
||||
public getCurrentSlide(): Element
|
||||
|
||||
public getIndices(slide?: Element): { h: number; v: number }
|
||||
|
||||
public getProgress(): number
|
||||
|
||||
public getTotalSlides(): number
|
||||
|
||||
public availableFragments(): { prev: boolean; next: boolean }
|
||||
|
||||
// Returns the speaker notes for the current slide
|
||||
public getSlideNotes(slide?: Element): string
|
||||
|
||||
// Plugins
|
||||
public hasPlugin(name: string): boolean
|
||||
|
||||
public getPlugin(name: string): Plugin
|
||||
|
||||
public getPlugins(): { [name: string]: Plugin }
|
||||
|
||||
// States
|
||||
// Added only the events we need
|
||||
public addEventListener(
|
||||
type: 'slidechanged',
|
||||
listener: (event: SlideEvent) => void,
|
||||
useCapture?: boolean
|
||||
): void
|
||||
public removeEventListener(
|
||||
type: 'slidechanged',
|
||||
listener: (event: SlideEvent) => void,
|
||||
useCapture?: boolean
|
||||
): void
|
||||
|
||||
// State Checks
|
||||
public isFirstSlide(): boolean
|
||||
|
||||
public isLastSlide(): boolean
|
||||
|
||||
public isPaused(): boolean
|
||||
|
||||
public isOverview(): boolean
|
||||
|
||||
public isAutoSliding(): boolean
|
||||
|
||||
// undocumented method
|
||||
public layout(): void
|
||||
|
||||
public addEventListeners(): void
|
||||
|
||||
public removeEventListeners(): void
|
||||
|
||||
public getSlide(x: number, y?: number): Element
|
||||
|
||||
public getScale(): number
|
||||
|
||||
public getConfig(): RevealOptions
|
||||
|
||||
// public getQueryHash(): any
|
||||
|
||||
// public setState(state: any): void
|
||||
|
||||
// public getState(): any
|
||||
|
||||
// update slides after dynamic changes
|
||||
public sync(): void
|
||||
}
|
||||
}
|
||||
|
||||
// [1]: Implement ourself can only modify the iframe url
|
|
@ -1,13 +1,13 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { extractFrontmatter } from '../../../../redux/note-details/frontmatter-extractor/extractor'
|
||||
import type { RawNoteFrontmatter } from '../../../../redux/note-details/raw-note-frontmatter-parser/types'
|
||||
import type { Linter } from './linter'
|
||||
import type { Diagnostic } from '@codemirror/lint'
|
||||
import type { EditorView } from '@codemirror/view'
|
||||
import { extractFrontmatter } from '@hedgedoc/commons'
|
||||
import { t } from 'i18next'
|
||||
import { load } from 'js-yaml'
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { SlideOptions } from '../../../redux/note-details/types/slide-show-options'
|
||||
import { Logger } from '../../../utils/logger'
|
||||
import type { SlideOptions } from '@hedgedoc/commons'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import type Reveal from 'reveal.js'
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { SlideOptions } from '../../redux/note-details/types/slide-show-options'
|
||||
import type { ScrollProps } from '../editor-page/synced-scroll/scroll-props'
|
||||
import type { CommonMarkdownRendererProps } from './common-markdown-renderer-props'
|
||||
import { RevealMarkdownExtension } from './extensions/reveal/reveal-markdown-extension'
|
||||
|
@ -12,6 +11,7 @@ import { useMarkdownExtensions } from './hooks/use-markdown-extensions'
|
|||
import { REVEAL_STATUS, useReveal } from './hooks/use-reveal'
|
||||
import { LoadingSlide } from './loading-slide'
|
||||
import { MarkdownToReact } from './markdown-to-react/markdown-to-react'
|
||||
import type { SlideOptions } from '@hedgedoc/commons'
|
||||
import React, { useEffect, useMemo, useRef } from 'react'
|
||||
|
||||
export interface SlideshowMarkdownRendererProps extends CommonMarkdownRendererProps {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { setDarkModePreference } from '../../redux/dark-mode/methods'
|
||||
import type { SlideOptions } from '../../redux/note-details/types/slide-show-options'
|
||||
import { useRendererToEditorCommunicator } from '../editor-page/render-context/renderer-to-editor-communicator-context-provider'
|
||||
import type { ScrollState } from '../editor-page/synced-scroll/scroll-props'
|
||||
import { eventEmitterContext } from '../markdown-renderer/hooks/use-extension-event-emitter'
|
||||
|
@ -14,6 +13,7 @@ import { useRendererReceiveHandler } from './window-post-message-communicator/ho
|
|||
import type { BaseConfiguration } from './window-post-message-communicator/rendering-message'
|
||||
import { CommunicationMessageType, RendererType } from './window-post-message-communicator/rendering-message'
|
||||
import { countWords } from './word-counter'
|
||||
import type { SlideOptions } from '@hedgedoc/commons/src/title-extraction/types/slide-show-options'
|
||||
import { EventEmitter2 } from 'eventemitter2'
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { DarkModePreference } from '../../../redux/dark-mode/types'
|
||||
import type { SlideOptions } from '../../../redux/note-details/types/slide-show-options'
|
||||
import type { ScrollState } from '../../editor-page/synced-scroll/scroll-props'
|
||||
import type { SlideOptions } from '@hedgedoc/commons'
|
||||
|
||||
export enum CommunicationMessageType {
|
||||
SET_MARKDOWN_CONTENT = 'SET_MARKDOWN_CONTENT',
|
||||
|
|
4
frontend/src/redux/application-state.d.ts
vendored
4
frontend/src/redux/application-state.d.ts
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
@ -7,10 +7,10 @@ import type { Config } from '../api/config/types'
|
|||
import type { HistoryEntryWithOrigin } from '../api/history/types'
|
||||
import type { DarkModeConfig } from './dark-mode/types'
|
||||
import type { EditorConfig } from './editor/types'
|
||||
import type { NoteDetails } from './note-details/types/note-details'
|
||||
import type { RealtimeStatus } from './realtime/types'
|
||||
import type { RendererStatus } from './renderer-status/types'
|
||||
import type { OptionalUserState } from './user/types'
|
||||
import type { NoteDetails } from '@hedgedoc/commons'
|
||||
|
||||
export interface ApplicationState {
|
||||
user: OptionalUserState
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { calculateLineStartIndexes } from './calculate-line-start-indexes'
|
||||
import { extractFrontmatter } from './frontmatter-extractor/extractor'
|
||||
import type { PresentFrontmatterExtractionResult } from './frontmatter-extractor/types'
|
||||
import { generateNoteTitle } from './generate-note-title'
|
||||
import { initialState } from './initial-state'
|
||||
import { createNoteFrontmatterFromYaml } from './raw-note-frontmatter-parser/parser'
|
||||
import type { NoteDetails } from './types/note-details'
|
||||
import { extractFrontmatter, generateNoteTitle } from '@hedgedoc/commons'
|
||||
import type { PresentFrontmatterExtractionResult } from '@hedgedoc/commons'
|
||||
|
||||
/**
|
||||
* Copies a {@link NoteDetails} but with another markdown content.
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { generateNoteTitle } from './generate-note-title'
|
||||
import { initialState } from './initial-state'
|
||||
|
||||
describe('generate note title', () => {
|
||||
it('will choose the frontmatter title first', () => {
|
||||
const actual = generateNoteTitle(
|
||||
{ ...initialState.frontmatter, title: 'frontmatter', opengraph: { title: 'opengraph' } },
|
||||
'first-heading'
|
||||
)
|
||||
expect(actual).toEqual('frontmatter')
|
||||
})
|
||||
|
||||
it('will choose the opengraph title second', () => {
|
||||
const actual = generateNoteTitle(
|
||||
{ ...initialState.frontmatter, opengraph: { title: 'opengraph' } },
|
||||
'first-heading'
|
||||
)
|
||||
expect(actual).toEqual('opengraph')
|
||||
})
|
||||
|
||||
it('will choose the first heading third', () => {
|
||||
const actual = generateNoteTitle({ ...initialState.frontmatter }, 'first-heading')
|
||||
expect(actual).toEqual('first-heading')
|
||||
})
|
||||
})
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { NoteDetails } from './types/note-details'
|
||||
import { NoteTextDirection, NoteType } from './types/note-details'
|
||||
import type { SlideOptions } from './types/slide-show-options'
|
||||
import { NoteTextDirection, NoteType } from '@hedgedoc/commons'
|
||||
import type { SlideOptions } from '@hedgedoc/commons'
|
||||
|
||||
export const initialSlideOptions: SlideOptions = {
|
||||
transition: 'zoom',
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { initialSlideOptions, initialState } from '../initial-state'
|
||||
import { ISO6391 } from '../types/iso6391'
|
||||
import type { Iso6391Language, NoteFrontmatter, OpenGraph } from '../types/note-details'
|
||||
import { NoteTextDirection, NoteType } from '../types/note-details'
|
||||
import type { SlideOptions } from '../types/slide-show-options'
|
||||
import type { RawNoteFrontmatter } from './types'
|
||||
import type { Iso6391Language, NoteFrontmatter, OpenGraph, SlideOptions } from '@hedgedoc/commons'
|
||||
import { ISO6391, NoteTextDirection, NoteType } from '@hedgedoc/commons'
|
||||
import { load } from 'js-yaml'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { generateNoteTitle } from '../generate-note-title'
|
||||
import type { NoteDetails } from '../types/note-details'
|
||||
import { generateNoteTitle } from '@hedgedoc/commons'
|
||||
|
||||
/**
|
||||
* Builds a {@link NoteDetails} redux state with an updated note title from frontmatter data and the first heading.
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { NoteMetadata } from '../../../api/notes/types'
|
||||
import type { CursorSelection } from '../../../components/editor-page/editor-pane/tool-bar/formatters/types/cursor-selection'
|
||||
import type { ISO6391 } from './iso6391'
|
||||
import type { SlideOptions } from './slide-show-options'
|
||||
import type { SlideOptions } from '@hedgedoc/commons'
|
||||
import type { NoteFrontmatter } from '@hedgedoc/commons'
|
||||
|
||||
type UnnecessaryNoteAttributes = 'updatedAt' | 'createdAt' | 'tags' | 'description'
|
||||
|
||||
|
@ -28,36 +28,6 @@ export interface NoteDetails extends Omit<NoteMetadata, UnnecessaryNoteAttribute
|
|||
frontmatterRendererInfo: RendererFrontmatterInfo
|
||||
}
|
||||
|
||||
export type Iso6391Language = (typeof ISO6391)[number]
|
||||
|
||||
export type OpenGraph = Record<string, string>
|
||||
|
||||
export interface NoteFrontmatter {
|
||||
title: string
|
||||
description: string
|
||||
tags: string[]
|
||||
robots: string
|
||||
lang: Iso6391Language
|
||||
dir: NoteTextDirection
|
||||
newlinesAreBreaks: boolean
|
||||
GA: string
|
||||
disqus: string
|
||||
license: string
|
||||
type: NoteType
|
||||
opengraph: OpenGraph
|
||||
slideOptions: SlideOptions
|
||||
}
|
||||
|
||||
export enum NoteTextDirection {
|
||||
LTR = 'ltr',
|
||||
RTL = 'rtl'
|
||||
}
|
||||
|
||||
export enum NoteType {
|
||||
DOCUMENT = '',
|
||||
SLIDE = 'slide'
|
||||
}
|
||||
|
||||
export interface RendererFrontmatterInfo {
|
||||
lineOffset: number
|
||||
frontmatterInvalid: boolean
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { RevealOptions } from 'reveal.js'
|
||||
|
||||
type WantedRevealOptions = 'autoSlide' | 'autoSlideStoppable' | 'transition' | 'backgroundTransition' | 'slideNumber'
|
||||
|
||||
export type SlideOptions = Required<Pick<RevealOptions, WantedRevealOptions>>
|
|
@ -2300,6 +2300,7 @@ __metadata:
|
|||
jest: 29.5.0
|
||||
microbundle: 0.15.1
|
||||
prettier: 2.8.7
|
||||
reveal.js: 4.4.0
|
||||
ts-jest: 29.0.5
|
||||
typescript: 5.0.2
|
||||
ws: 8.13.0
|
||||
|
|
Loading…
Reference in a new issue