Commit 8c845e28 by Яков

update iframe and video

parent e1b05324
{ {
"name": "react-ag-qeditor", "name": "react-ag-qeditor",
"version": "1.1.24", "version": "1.1.25",
"description": "WYSIWYG html editor", "description": "WYSIWYG html editor",
"author": "atma", "author": "atma",
"license": "MIT", "license": "MIT",
......
...@@ -18,8 +18,17 @@ const getStyleForAlign = (align) => { ...@@ -18,8 +18,17 @@ const getStyleForAlign = (align) => {
return style return style
} }
const getOuterAlignStyle = (align) => {
return {
width: '100%',
display: 'block',
textAlign: align === 'center' ? 'center' : align === 'right' ? 'right' : 'left',
}
}
const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected }) => { const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected }) => {
const wrapperRef = useRef(null) const outerRef = useRef(null)
const innerRef = useRef(null)
const iframeRef = useRef(null) const iframeRef = useRef(null)
const [showAlignMenu, setShowAlignMenu] = useState(false) const [showAlignMenu, setShowAlignMenu] = useState(false)
...@@ -36,10 +45,9 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected ...@@ -36,10 +45,9 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected
const paddingRight = parseFloat(editorStyles.paddingRight) || 0 const paddingRight = parseFloat(editorStyles.paddingRight) || 0
const availableEditorWidth = fullEditorWidth - paddingLeft - paddingRight const availableEditorWidth = fullEditorWidth - paddingLeft - paddingRight
// важно: стартуем от parentElement, чтобы не схватить wrapperRef.current // важно: стартуем от parentElement, чтобы не схватить innerRef.current
const startEl = wrapperRef.current?.parentElement || editorContent const startEl = outerRef.current?.parentElement || editorContent
const container = const container = startEl.closest('li, blockquote, td, p, div') || editorContent
startEl.closest('li, blockquote, td, p, div') || editorContent
const containerStyles = window.getComputedStyle(container) const containerStyles = window.getComputedStyle(container)
const containerPaddingLeft = parseFloat(containerStyles.paddingLeft) || 0 const containerPaddingLeft = parseFloat(containerStyles.paddingLeft) || 0
...@@ -49,7 +57,6 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected ...@@ -49,7 +57,6 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected
return { width: containerWidth, availableSpace: availableEditorWidth } return { width: containerWidth, availableSpace: availableEditorWidth }
} }
const safeUpdateAttributes = (newAttrs) => { const safeUpdateAttributes = (newAttrs) => {
const { width: containerWidth, availableSpace } = getEditorDimensions() const { width: containerWidth, availableSpace } = getEditorDimensions()
...@@ -57,7 +64,8 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected ...@@ -57,7 +64,8 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected
let height = newAttrs.height ?? node.attrs.height let height = newAttrs.height ?? node.attrs.height
if (typeof width === 'number' && typeof height === 'number') { if (typeof width === 'number' && typeof height === 'number') {
const maxWidth = node.attrs.align === 'center' ? containerWidth : availableSpace const maxWidth = (newAttrs.align ?? node.attrs.align) === 'center' ? containerWidth : availableSpace
if (width > maxWidth) { if (width > maxWidth) {
const ratio = maxWidth / width const ratio = maxWidth / width
width = maxWidth width = maxWidth
...@@ -117,14 +125,14 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected ...@@ -117,14 +125,14 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected
console.warn('getPos() failed:', err) console.warn('getPos() failed:', err)
} }
const startWidth = node.attrs.width || iframeRef.current?.clientWidth || 560 const startWidth = node.attrs.width || innerRef.current?.clientWidth || 560
const startHeight = node.attrs.height || iframeRef.current?.clientHeight || 315 const startHeight = node.attrs.height || innerRef.current?.clientHeight || 315
const aspectRatio = startWidth / startHeight const aspectRatio = startWidth / startHeight
const startX = e.clientX const startX = e.clientX
const startY = e.clientY const startY = e.clientY
const { width: containerWidth, availableSpace } = getEditorDimensions() const { width: containerWidth, availableSpace } = getEditorDimensions()
const maxWidth = node.attrs.align === 'center' ? containerWidth : availableSpace const maxWidth = (node.attrs.align || 'left') === 'center' ? containerWidth : availableSpace
const onMouseMove = (ev) => { const onMouseMove = (ev) => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
...@@ -177,31 +185,24 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected ...@@ -177,31 +185,24 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected
const align = node.attrs.align || 'left' const align = node.attrs.align || 'left'
const wrapperStyle = { const outerStyle = getOuterAlignStyle(align)
const innerStyle = {
position: 'relative', position: 'relative',
display: 'inline-block',
width: node.attrs.width ? `${node.attrs.width}px` : undefined, width: node.attrs.width ? `${node.attrs.width}px` : undefined,
height: node.attrs.height ? `${node.attrs.height}px` : undefined, height: node.attrs.height ? `${node.attrs.height}px` : undefined,
// align styles inside editor
display: align === 'center' ? 'block' : 'inline-block',
marginLeft: align === 'center' ? 'auto' : undefined,
marginRight: align === 'center' ? 'auto' : undefined,
float: align === 'left' ? 'left' : align === 'right' ? 'right' : 'none',
// чтобы текст красиво обтекал
marginInlineEnd: align === 'left' ? '1rem' : undefined,
marginInlineStart: align === 'right' ? '1rem' : undefined,
} }
return ( return (
<NodeViewWrapper <NodeViewWrapper
ref={wrapperRef} ref={outerRef}
as="div" as="div"
className="atma-iframe-wrapper" className="atma-iframe-wrapper"
style={wrapperStyle} style={outerStyle}
data-align={node.attrs.align || 'left'} data-align={align}
> >
<div ref={innerRef} style={innerStyle}>
<iframe <iframe
ref={iframeRef} ref={iframeRef}
src={node.attrs.src} src={node.attrs.src}
...@@ -272,21 +273,21 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected ...@@ -272,21 +273,21 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected
display: 'flex', display: 'flex',
}} }}
> >
{ALIGN_OPTIONS.map((align) => ( {ALIGN_OPTIONS.map((a) => (
<button <button
type="button" type="button"
key={align} key={a}
onClick={() => handleAlign(align)} onClick={() => handleAlign(a)}
style={{ style={{
margin: '0 2px', margin: '0 2px',
padding: '10px 8px', padding: '10px 8px',
background: node.attrs.align === align ? '#e6f7ff' : 'transparent', background: align === a ? '#e6f7ff' : 'transparent',
border: '1px solid #d9d9d9', border: '1px solid #d9d9d9',
borderRadius: 2, borderRadius: 2,
cursor: 'pointer', cursor: 'pointer',
}} }}
> >
{align} {a}
</button> </button>
))} ))}
</div> </div>
...@@ -316,6 +317,7 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected ...@@ -316,6 +317,7 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected
</button> </button>
</Fragment> </Fragment>
)} )}
</div>
</NodeViewWrapper> </NodeViewWrapper>
) )
} }
......
...@@ -18,8 +18,17 @@ const getStyleForAlign = (align) => { ...@@ -18,8 +18,17 @@ const getStyleForAlign = (align) => {
return style return style
} }
const getOuterAlignStyle = (align) => {
return {
width: '100%',
display: 'block',
textAlign: align === 'center' ? 'center' : align === 'right' ? 'right' : 'left',
}
}
const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected }) => { const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected }) => {
const wrapperRef = useRef(null) const outerRef = useRef(null)
const innerRef = useRef(null)
const videoRef = useRef(null) const videoRef = useRef(null)
const [showAlignMenu, setShowAlignMenu] = useState(false) const [showAlignMenu, setShowAlignMenu] = useState(false)
...@@ -36,7 +45,9 @@ const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected } ...@@ -36,7 +45,9 @@ const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected }
const paddingRight = parseFloat(editorStyles.paddingRight) || 0 const paddingRight = parseFloat(editorStyles.paddingRight) || 0
const availableEditorWidth = fullEditorWidth - paddingLeft - paddingRight const availableEditorWidth = fullEditorWidth - paddingLeft - paddingRight
const container = wrapperRef.current?.closest('li, blockquote, td, p, div') || editorContent const startEl = outerRef.current?.parentElement || editorContent
const container = startEl.closest('li, blockquote, td, p, div') || editorContent
const containerStyles = window.getComputedStyle(container) const containerStyles = window.getComputedStyle(container)
const containerPaddingLeft = parseFloat(containerStyles.paddingLeft) || 0 const containerPaddingLeft = parseFloat(containerStyles.paddingLeft) || 0
const containerPaddingRight = parseFloat(containerStyles.paddingRight) || 0 const containerPaddingRight = parseFloat(containerStyles.paddingRight) || 0
...@@ -52,7 +63,8 @@ const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected } ...@@ -52,7 +63,8 @@ const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected }
let height = newAttrs.height ?? node.attrs.height let height = newAttrs.height ?? node.attrs.height
if (typeof width === 'number' && typeof height === 'number') { if (typeof width === 'number' && typeof height === 'number') {
const maxWidth = node.attrs.align === 'center' ? containerWidth : availableSpace const maxWidth = (newAttrs.align ?? node.attrs.align) === 'center' ? containerWidth : availableSpace
if (width > maxWidth) { if (width > maxWidth) {
const ratio = maxWidth / width const ratio = maxWidth / width
width = maxWidth width = maxWidth
...@@ -112,14 +124,14 @@ const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected } ...@@ -112,14 +124,14 @@ const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected }
console.warn('getPos() failed:', err) console.warn('getPos() failed:', err)
} }
const startWidth = node.attrs.width || videoRef.current?.clientWidth || 640 const startWidth = node.attrs.width || innerRef.current?.clientWidth || 640
const startHeight = node.attrs.height || videoRef.current?.clientHeight || 360 const startHeight = node.attrs.height || innerRef.current?.clientHeight || 360
const aspectRatio = startWidth / startHeight const aspectRatio = startWidth / startHeight
const startX = e.clientX const startX = e.clientX
const startY = e.clientY const startY = e.clientY
const { width: containerWidth, availableSpace } = getEditorDimensions() const { width: containerWidth, availableSpace } = getEditorDimensions()
const maxWidth = node.attrs.align === 'center' ? containerWidth : availableSpace const maxWidth = (node.attrs.align || 'left') === 'center' ? containerWidth : availableSpace
const onMouseMove = (ev) => { const onMouseMove = (ev) => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
...@@ -170,21 +182,26 @@ const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected } ...@@ -170,21 +182,26 @@ const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected }
} }
} }
const wrapperStyle = { const align = node.attrs.align || 'left'
const outerStyle = getOuterAlignStyle(align)
const innerStyle = {
position: 'relative', position: 'relative',
display: node.attrs.align === 'center' ? 'block' : 'inline-block', display: 'inline-block',
width: node.attrs.width ? `${node.attrs.width}px` : undefined, width: node.attrs.width ? `${node.attrs.width}px` : undefined,
height: node.attrs.height ? `${node.attrs.height}px` : undefined, height: node.attrs.height ? `${node.attrs.height}px` : undefined,
} }
return ( return (
<NodeViewWrapper <NodeViewWrapper
ref={wrapperRef} ref={outerRef}
as="div" as="div"
className="atma-video-wrapper" className="atma-video-wrapper"
style={wrapperStyle} style={outerStyle}
data-align={node.attrs.align || 'left'} data-align={align}
> >
<div ref={innerRef} style={innerStyle}>
<video <video
ref={videoRef} ref={videoRef}
src={node.attrs.src} src={node.attrs.src}
...@@ -254,21 +271,21 @@ const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected } ...@@ -254,21 +271,21 @@ const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected }
display: 'flex', display: 'flex',
}} }}
> >
{ALIGN_OPTIONS.map((align) => ( {ALIGN_OPTIONS.map((a) => (
<button <button
type="button" type="button"
key={align} key={a}
onClick={() => handleAlign(align)} onClick={() => handleAlign(a)}
style={{ style={{
margin: '0 2px', margin: '0 2px',
padding: '10px 8px', padding: '10px 8px',
background: node.attrs.align === align ? '#e6f7ff' : 'transparent', background: align === a ? '#e6f7ff' : 'transparent',
border: '1px solid #d9d9d9', border: '1px solid #d9d9d9',
borderRadius: 2, borderRadius: 2,
cursor: 'pointer', cursor: 'pointer',
}} }}
> >
{align} {a}
</button> </button>
))} ))}
</div> </div>
...@@ -298,6 +315,7 @@ const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected } ...@@ -298,6 +315,7 @@ const ResizableVideoView = ({ editor, node, updateAttributes, getPos, selected }
</button> </button>
</Fragment> </Fragment>
)} )}
</div>
</NodeViewWrapper> </NodeViewWrapper>
) )
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment