From cf34df21b7f195933397d2f26a492fbb206110e2 Mon Sep 17 00:00:00 2001 From: Erik Michelson Date: Mon, 13 Feb 2023 17:33:36 +0100 Subject: [PATCH] feat: add license frontmatter field for link header This commit adds the "license" frontmatter property which sets a link with the "license" relation in the head of the HTML page. Furthermore, this commit restructures the other head elements for a note altogether into a single component that can be used to inject all head elements at once. Signed-off-by: Erik Michelson --- .../editor-page/editor-page-content.tsx | 6 ++--- .../head-meta-properties.tsx | 22 +++++++++++++++++ .../license-link-head.tsx | 24 +++++++++++++++++++ .../note-and-app-title-head.tsx | 6 ++--- .../opengraph-head.tsx | 0 frontend/src/pages/p/[noteId].tsx | 4 ++-- frontend/src/pages/s/[noteId].tsx | 4 ++-- .../src/redux/note-details/initial-state.ts | 1 + .../raw-note-frontmatter-parser/parser.ts | 1 + .../raw-note-frontmatter-parser/types.d.ts | 1 + .../redux/note-details/types/note-details.ts | 1 + 11 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 frontend/src/components/editor-page/head-meta-properties/head-meta-properties.tsx create mode 100644 frontend/src/components/editor-page/head-meta-properties/license-link-head.tsx rename frontend/src/components/{layout => editor-page/head-meta-properties}/note-and-app-title-head.tsx (71%) rename frontend/src/components/editor-page/{opengraph-head => head-meta-properties}/opengraph-head.tsx (100%) diff --git a/frontend/src/components/editor-page/editor-page-content.tsx b/frontend/src/components/editor-page/editor-page-content.tsx index 473a0fa98..b4d387545 100644 --- a/frontend/src/components/editor-page/editor-page-content.tsx +++ b/frontend/src/components/editor-page/editor-page-content.tsx @@ -8,7 +8,6 @@ import { useApplyDarkMode } from '../../hooks/common/use-apply-dark-mode' import { updateNoteTitleByFirstHeading } from '../../redux/note-details/methods' import { Logger } from '../../utils/logger' import { MotdModal } from '../common/motd-modal/motd-modal' -import { NoteAndAppTitleHead } from '../layout/note-and-app-title-head' import { CommunicatorImageLightbox } from '../markdown-renderer/extensions/image/communicator-image-lightbox' import { ExtensionEventEmitterProvider } from '../markdown-renderer/hooks/use-extension-event-emitter' import { AppBar, AppBarMode } from './app-bar/app-bar' @@ -16,8 +15,8 @@ import { ChangeEditorContentContextProvider } from './change-content-context/cha import { EditorDocumentRenderer } from './editor-document-renderer/editor-document-renderer' import { EditorPane } from './editor-pane/editor-pane' import { useComponentsFromAppExtensions } from './editor-pane/hooks/use-components-from-app-extensions' +import { HeadMetaProperties } from './head-meta-properties/head-meta-properties' import { useUpdateLocalHistoryEntry } from './hooks/use-update-local-history-entry' -import { OpengraphHead } from './opengraph-head/opengraph-head' import { Sidebar } from './sidebar/sidebar' import { Splitter } from './splitter/splitter' import type { DualScrollState, ScrollState } from './synced-scroll/scroll-props' @@ -128,8 +127,7 @@ export const EditorPageContent: React.FC = () => { {editorExtensionComponents} - - +
diff --git a/frontend/src/components/editor-page/head-meta-properties/head-meta-properties.tsx b/frontend/src/components/editor-page/head-meta-properties/head-meta-properties.tsx new file mode 100644 index 000000000..33bd3b2db --- /dev/null +++ b/frontend/src/components/editor-page/head-meta-properties/head-meta-properties.tsx @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { LicenseLinkHead } from './license-link-head' +import { NoteAndAppTitleHead } from './note-and-app-title-head' +import { OpengraphHead } from './opengraph-head' +import React, { Fragment } from 'react' + +/** + * Renders all HTML head tags that should be present for a note. + */ +export const HeadMetaProperties: React.FC = () => { + return ( + + + + + + ) +} diff --git a/frontend/src/components/editor-page/head-meta-properties/license-link-head.tsx b/frontend/src/components/editor-page/head-meta-properties/license-link-head.tsx new file mode 100644 index 000000000..ac2f34035 --- /dev/null +++ b/frontend/src/components/editor-page/head-meta-properties/license-link-head.tsx @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { useApplicationState } from '../../../hooks/common/use-application-state' +import Head from 'next/head' +import React, { useMemo } from 'react' + +/** + * Renders the license link tag if a license is set in the frontmatter. + */ +export const LicenseLinkHead: React.FC = () => { + const license = useApplicationState((state) => state.noteDetails.frontmatter.license) + + const optionalLinkElement = useMemo(() => { + if (!license || license.trim() === '') { + return null + } + return + }, [license]) + + return {optionalLinkElement} +} diff --git a/frontend/src/components/layout/note-and-app-title-head.tsx b/frontend/src/components/editor-page/head-meta-properties/note-and-app-title-head.tsx similarity index 71% rename from frontend/src/components/layout/note-and-app-title-head.tsx rename to frontend/src/components/editor-page/head-meta-properties/note-and-app-title-head.tsx index ca290b9aa..ae1625f8f 100644 --- a/frontend/src/components/layout/note-and-app-title-head.tsx +++ b/frontend/src/components/editor-page/head-meta-properties/note-and-app-title-head.tsx @@ -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 { useAppTitle } from '../../hooks/common/use-app-title' -import { useNoteTitle } from '../../hooks/common/use-note-title' +import { useAppTitle } from '../../../hooks/common/use-app-title' +import { useNoteTitle } from '../../../hooks/common/use-note-title' import Head from 'next/head' import React, { useMemo } from 'react' diff --git a/frontend/src/components/editor-page/opengraph-head/opengraph-head.tsx b/frontend/src/components/editor-page/head-meta-properties/opengraph-head.tsx similarity index 100% rename from frontend/src/components/editor-page/opengraph-head/opengraph-head.tsx rename to frontend/src/components/editor-page/head-meta-properties/opengraph-head.tsx diff --git a/frontend/src/pages/p/[noteId].tsx b/frontend/src/pages/p/[noteId].tsx index ed10e4def..e57fafdfc 100644 --- a/frontend/src/pages/p/[noteId].tsx +++ b/frontend/src/pages/p/[noteId].tsx @@ -4,8 +4,8 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { NoteLoadingBoundary } from '../../components/common/note-loading-boundary/note-loading-boundary' +import { HeadMetaProperties } from '../../components/editor-page/head-meta-properties/head-meta-properties' import { EditorToRendererCommunicatorContextProvider } from '../../components/editor-page/render-context/editor-to-renderer-communicator-context-provider' -import { NoteAndAppTitleHead } from '../../components/layout/note-and-app-title-head' import { SlideShowPageContent } from '../../components/slide-show-page/slide-show-page-content' import React from 'react' @@ -15,7 +15,7 @@ import React from 'react' export const SlideShowPage: React.FC = () => { return ( - + diff --git a/frontend/src/pages/s/[noteId].tsx b/frontend/src/pages/s/[noteId].tsx index f7164b170..3db1342b3 100644 --- a/frontend/src/pages/s/[noteId].tsx +++ b/frontend/src/pages/s/[noteId].tsx @@ -7,8 +7,8 @@ import { MotdModal } from '../../components/common/motd-modal/motd-modal' import { NoteLoadingBoundary } from '../../components/common/note-loading-boundary/note-loading-boundary' import { DocumentReadOnlyPageContent } from '../../components/document-read-only-page/document-read-only-page-content' import { AppBar, AppBarMode } from '../../components/editor-page/app-bar/app-bar' +import { HeadMetaProperties } from '../../components/editor-page/head-meta-properties/head-meta-properties' import { EditorToRendererCommunicatorContextProvider } from '../../components/editor-page/render-context/editor-to-renderer-communicator-context-provider' -import { NoteAndAppTitleHead } from '../../components/layout/note-and-app-title-head' import { useApplyDarkMode } from '../../hooks/common/use-apply-dark-mode' import React from 'react' @@ -20,7 +20,7 @@ export const DocumentReadOnlyPage: React.FC = () => { return ( - +
diff --git a/frontend/src/redux/note-details/initial-state.ts b/frontend/src/redux/note-details/initial-state.ts index 62bac3662..a3cd708e1 100644 --- a/frontend/src/redux/note-details/initial-state.ts +++ b/frontend/src/redux/note-details/initial-state.ts @@ -54,6 +54,7 @@ export const initialState: NoteDetails = { newlinesAreBreaks: true, GA: '', disqus: '', + license: '', type: NoteType.DOCUMENT, opengraph: {}, slideOptions: initialSlideOptions diff --git a/frontend/src/redux/note-details/raw-note-frontmatter-parser/parser.ts b/frontend/src/redux/note-details/raw-note-frontmatter-parser/parser.ts index 12471d62c..8f47ba9b1 100644 --- a/frontend/src/redux/note-details/raw-note-frontmatter-parser/parser.ts +++ b/frontend/src/redux/note-details/raw-note-frontmatter-parser/parser.ts @@ -48,6 +48,7 @@ const parseRawNoteFrontmatter = (rawData: RawNoteFrontmatter): NoteFrontmatter = dir: parseTextDirection(rawData), opengraph: parseOpenGraph(rawData), slideOptions: parseSlideOptions(rawData), + license: rawData.license ?? initialState.frontmatter.license, tags } } diff --git a/frontend/src/redux/note-details/raw-note-frontmatter-parser/types.d.ts b/frontend/src/redux/note-details/raw-note-frontmatter-parser/types.d.ts index d0c485de7..470c9d5e4 100644 --- a/frontend/src/redux/note-details/raw-note-frontmatter-parser/types.d.ts +++ b/frontend/src/redux/note-details/raw-note-frontmatter-parser/types.d.ts @@ -14,6 +14,7 @@ export interface RawNoteFrontmatter { breaks: boolean | undefined GA: string | undefined disqus: string | undefined + license: string | undefined type: string | undefined slideOptions: { [key: string]: string } | null opengraph: { [key: string]: string } | null diff --git a/frontend/src/redux/note-details/types/note-details.ts b/frontend/src/redux/note-details/types/note-details.ts index 347cdeebf..eb91525a5 100644 --- a/frontend/src/redux/note-details/types/note-details.ts +++ b/frontend/src/redux/note-details/types/note-details.ts @@ -42,6 +42,7 @@ export interface NoteFrontmatter { newlinesAreBreaks: boolean GA: string disqus: string + license: string type: NoteType opengraph: OpenGraph slideOptions: SlideOptions