diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx
index ec6c565a..d956b58b 100644
--- a/src/components/Article/FullArticle.tsx
+++ b/src/components/Article/FullArticle.tsx
@@ -4,7 +4,7 @@ import { getPagePath } from '@nanostores/router'
import { createPopper } from '@popperjs/core'
import { Link, Meta } from '@solidjs/meta'
import { clsx } from 'clsx'
-import { createEffect, For, createMemo, onMount, Show, createSignal, onCleanup } from 'solid-js'
+import { createEffect, For, createMemo, onMount, Show, createSignal, onCleanup, on } from 'solid-js'
import { isServer } from 'solid-js/web'
import { useLocalize } from '../../context/localize'
@@ -44,6 +44,11 @@ type Props = {
scrollToComments?: boolean
}
+type IframeSize = {
+ width: number
+ height: number
+}
+
export type ArticlePageSearchParams = {
scrollTo: 'comments'
commentId: string
@@ -182,18 +187,6 @@ export const FullArticle = (props: Props) => {
actions: { loadReactionsBy },
} = useReactions()
- onMount(async () => {
- await loadReactionsBy({
- by: { shout: props.article.slug },
- })
-
- setIsReactionsLoaded(true)
- })
-
- onMount(() => {
- document.title = props.article.title
- })
-
const clickHandlers = []
const documentClickHandlers = []
@@ -295,8 +288,50 @@ export const FullArticle = (props: Props) => {
}
}
- const cover = props.article.cover ?? 'production/image/logo_image.png'
+ // Check iframes size
+ const articleContainer: { current: HTMLElement } = { current: null }
+ const updateIframeSizes = () => {
+ if (!articleContainer?.current || !props.article.body) return
+ const iframes = articleContainer?.current?.querySelectorAll('iframe')
+ if (!iframes) return
+ const containerWidth = articleContainer.current?.offsetWidth
+ iframes.forEach((iframe) => {
+ const style = window.getComputedStyle(iframe)
+ const originalWidth = iframe.getAttribute('width') || style.width.replace('px', '')
+ const originalHeight = iframe.getAttribute('height') || style.height.replace('px', '')
+ const width = Number(originalWidth)
+ const height = Number(originalHeight)
+
+ if (containerWidth < width) {
+ const aspectRatio = width / height
+ iframe.style.width = `${containerWidth}px`
+ iframe.style.height = `${Math.round(containerWidth / aspectRatio) + 40}px`
+ }
+ })
+ }
+
+ createEffect(
+ on(
+ () => props.article,
+ () => {
+ updateIframeSizes()
+ },
+ ),
+ )
+
+ onMount(async () => {
+ await loadReactionsBy({
+ by: { shout: props.article.slug },
+ })
+ setIsReactionsLoaded(true)
+ document.title = props.article.title
+ window?.addEventListener('resize', updateIframeSizes)
+
+ onCleanup(() => window.removeEventListener('resize', updateIframeSizes))
+ })
+
+ const cover = props.article.cover ?? 'production/image/logo_image.png'
const ogImage = getOpenGraphImageUrl(cover, {
title: props.article.title,
topic: mainTopic().title,
@@ -328,6 +363,7 @@ export const FullArticle = (props: Props) => {
(articleContainer.current = el)}
class={clsx('col-md-16 col-lg-14 col-xl-12 offset-md-5', styles.articleContent)}
onClick={handleArticleBodyClick}
>
diff --git a/src/components/Editor/Editor.tsx b/src/components/Editor/Editor.tsx
index 101f9af2..dafaa7f0 100644
--- a/src/components/Editor/Editor.tsx
+++ b/src/components/Editor/Editor.tsx
@@ -46,6 +46,8 @@ import { Figcaption } from './extensions/Figcaption'
import { Figure } from './extensions/Figure'
import { Footnote } from './extensions/Footnote'
import { Iframe } from './extensions/Iframe'
+import { Span } from './extensions/Span'
+import { ToggleTextWrap } from './extensions/ToggleTextWrap'
import { TrailingNode } from './extensions/TrailingNode'
import { TextBubbleMenu } from './TextBubbleMenu'
@@ -201,6 +203,8 @@ export const Editor = (props: Props) => {
CustomBlockquote,
Bold,
Italic,
+ Span,
+ ToggleTextWrap,
Strike,
HorizontalRule.configure({
HTMLAttributes: {
@@ -208,7 +212,10 @@ export const Editor = (props: Props) => {
},
}),
Underline,
- Link.configure({
+ Link.extend({
+ inclusive: false,
+ }).configure({
+ autolink: true,
openOnClick: false,
}),
Heading.configure({
@@ -244,6 +251,7 @@ export const Editor = (props: Props) => {
Figure,
Figcaption,
Footnote,
+ ToggleTextWrap,
CharacterCount.configure(), // https://github.com/ueberdosis/tiptap/issues/2589#issuecomment-1093084689
BubbleMenu.configure({
pluginKey: 'textBubbleMenu',
@@ -252,6 +260,9 @@ export const Editor = (props: Props) => {
const { doc, selection } = state
const { empty } = selection
const isEmptyTextBlock = doc.textBetween(from, to).length === 0 && isTextSelection(selection)
+ if (isEmptyTextBlock) {
+ e.chain().focus().removeTextWrap({ class: 'highlight-fake-selection' }).run()
+ }
setIsCommonMarkup(e.isActive('figcaption'))
const result =
(view.hasFocus() &&
diff --git a/src/components/Editor/Prosemirror.scss b/src/components/Editor/Prosemirror.scss
index d84e01da..ca78c9f1 100644
--- a/src/components/Editor/Prosemirror.scss
+++ b/src/components/Editor/Prosemirror.scss
@@ -311,3 +311,10 @@ footnote {
background-color: unset;
}
}
+
+.highlight-fake-selection {
+ background: var(--selection-background);
+ color: var(--selection-color);
+ border: solid var(--selection-background);
+ border-width: 5px 0;
+}
diff --git a/src/components/Editor/SimplifiedEditor.tsx b/src/components/Editor/SimplifiedEditor.tsx
index a4aa4d7b..a549781e 100644
--- a/src/components/Editor/SimplifiedEditor.tsx
+++ b/src/components/Editor/SimplifiedEditor.tsx
@@ -117,7 +117,10 @@ const SimplifiedEditor = (props: Props) => {
Paragraph,
Bold,
Italic,
- Link.configure({
+ Link.extend({
+ inclusive: false,
+ }).configure({
+ autolink: true,
openOnClick: false,
}),
CharacterCount.configure({
diff --git a/src/components/Editor/TextBubbleMenu/TextBubbleMenu.tsx b/src/components/Editor/TextBubbleMenu/TextBubbleMenu.tsx
index c7bb2d32..7457b009 100644
--- a/src/components/Editor/TextBubbleMenu/TextBubbleMenu.tsx
+++ b/src/components/Editor/TextBubbleMenu/TextBubbleMenu.tsx
@@ -129,11 +129,21 @@ export const TextBubbleMenu = (props: BubbleMenuProps) => {
})
})
+ const handleOpenLinkForm = () => {
+ props.editor.chain().focus().addTextWrap({ class: 'highlight-fake-selection' }).run()
+ setLinkEditorOpen(true)
+ }
+
+ const handleCloseLinkForm = () => {
+ setLinkEditorOpen(false)
+ props.editor.chain().focus().removeTextWrap({ class: 'highlight-fake-selection' }).run()
+ }
+
return (