Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
lib
react-ag-qeditor
Commits
934d6b2b
Commit
934d6b2b
authored
Jan 17, 2024
by
yakoff94
Browse files
fix resizer
parent
70b17b67
Changes
2
Show whitespace changes
Inline
Side-by-side
src/QEditor.jsx
View file @
934d6b2b
...
...
@@ -22,6 +22,7 @@ import TextStyle from '@tiptap/extension-text-style'
import
Superscript
from
'
@tiptap/extension-superscript
'
import
Subscript
from
'
@tiptap/extension-subscript
'
// import ImageResize from 'tiptap-imagresize'
import
ToolBar
from
'
./components/ToolBar
'
import
EditorModal
from
'
./components/EditorModal
'
import
Uploader
from
'
./components/Uploader
'
...
...
@@ -38,6 +39,7 @@ import IframeModal from './modals/IframeModal'
import
IframeCustomModal
from
'
./modals/IframeCustomModal
'
import
{
isMobile
}
from
'
react-device-detect
'
import
Resizable
from
'
./extensions/Resizing
'
import
Resizing
from
"
./extensions/Resizing
"
;
const
initialBubbleItems
=
[
'
bold
'
,
...
...
@@ -55,8 +57,8 @@ const QEditor = ({
value
,
onChange
=
()
=>
{},
style
,
uploadOptions
=
{
url
:
''
,
errorMessage
:
''
},
toolsOptions
=
{
type
:
'
all
'
}
uploadOptions
=
{
url
:
''
,
errorMessage
:
''
},
toolsOptions
=
{
type
:
'
all
'
}
})
=>
{
global
.
uploadUrl
=
uploadOptions
.
url
...
...
@@ -71,7 +73,7 @@ const QEditor = ({
const
[
focusFromTo
,
setFocusFromTo
]
=
useState
(
null
)
const
[
oldFocusFromTo
,
setOldFocusFromTo
]
=
useState
(
null
)
const
[
isUploading
,
setIsUploading
]
=
useState
(
false
)
const
[
recordType
,
setRecordType
]
=
useState
({
video
:
true
})
const
[
recordType
,
setRecordType
]
=
useState
({
video
:
true
})
// eslint-disable-next-line no-unused-vars
const
getRgb
=
(
hex
)
=>
{
...
...
@@ -167,12 +169,7 @@ const QEditor = ({
}
// update link
editor
.
chain
()
.
focus
()
.
extendMarkRange
(
'
link
'
)
.
setLink
({
href
:
url
,
target
:
'
_blank
'
})
.
run
()
editor
.
chain
().
focus
().
extendMarkRange
(
'
link
'
).
setLink
({
href
:
url
,
target
:
'
_blank
'
}).
run
()
}
},
file
:
{
...
...
@@ -209,15 +206,15 @@ const QEditor = ({
},
h2
:
{
title
:
'
Заголовок 2
'
,
onClick
:
()
=>
editor
.
chain
().
focus
().
toggleHeading
({
level
:
2
}).
run
()
onClick
:
()
=>
editor
.
chain
().
focus
().
toggleHeading
({
level
:
2
}).
run
()
},
h3
:
{
title
:
'
Заголовок 3
'
,
onClick
:
()
=>
editor
.
chain
().
focus
().
toggleHeading
({
level
:
3
}).
run
()
onClick
:
()
=>
editor
.
chain
().
focus
().
toggleHeading
({
level
:
3
}).
run
()
},
h4
:
{
title
:
'
Заголовок 4
'
,
onClick
:
()
=>
editor
.
chain
().
focus
().
toggleHeading
({
level
:
4
}).
run
()
onClick
:
()
=>
editor
.
chain
().
focus
().
toggleHeading
({
level
:
4
}).
run
()
},
paragraph
:
{
title
:
'
Обычный
'
,
...
...
@@ -293,8 +290,8 @@ const QEditor = ({
alignCenter
:
{
title
:
'
По центру
'
,
onClick
:
()
=>
{
editor
.
commands
.
setTextAlign
(
'
center
'
)
editor
.
chain
().
focus
()
editor
.
commands
.
setTextAlign
(
'
center
'
)
;
editor
.
chain
().
focus
()
;
}
},
alignRight
:
{
...
...
@@ -307,7 +304,7 @@ const QEditor = ({
insertTable
:
{
title
:
'
Вставить таблицу
'
,
onClick
:
()
=>
editor
.
chain
().
focus
().
insertTable
({
rows
:
2
,
cols
:
2
}).
run
()
editor
.
chain
().
focus
().
insertTable
({
rows
:
2
,
cols
:
2
}).
run
()
},
deleteTable
:
{
title
:
'
Удалить таблицу
'
,
...
...
@@ -359,7 +356,7 @@ const QEditor = ({
voicemessage
:
{
title
:
'
Записать голосовое сообщение
'
,
onClick
:
()
=>
{
setRecordType
({
audio
:
true
})
setRecordType
({
audio
:
true
})
clearBlobUrl
()
modalOpener
(
'
voicemessage
'
,
'
Записать голосовое сообщение
'
)
}
...
...
@@ -367,7 +364,7 @@ const QEditor = ({
webcamera
:
{
title
:
'
Записать с камеры
'
,
onClick
:
()
=>
{
setRecordType
({
video
:
true
})
setRecordType
({
video
:
true
})
clearBlobUrl
()
modalOpener
(
'
webcamera
'
,
'
Записать с камеры
'
)
}
...
...
@@ -376,9 +373,9 @@ const QEditor = ({
title
:
'
Записать экран
'
,
onClick
:
()
=>
{
if
(
isMobile
)
{
setRecordType
({
video
:
true
})
setRecordType
({
video
:
true
})
}
else
{
setRecordType
({
screen
:
true
})
setRecordType
({
screen
:
true
})
}
clearBlobUrl
()
modalOpener
(
'
screencust
'
,
'
Записать экран
'
)
...
...
@@ -402,6 +399,7 @@ const QEditor = ({
Image
.
configure
({
inline
:
true
}),
// ImageResize.configure({resizeIcon: <>ResizeMe</>,
Resizable
.
configure
({
types
:
[
"
image
"
],
// resizable type
handlerStyle
:
{
// handler point style
...
...
@@ -456,8 +454,8 @@ const QEditor = ({
Subscript
],
content
:
value
,
onUpdate
:
({
editor
})
=>
onChange
(
editor
.
getHTML
()),
onFocus
:
({
editor
})
=>
{
onUpdate
:
({
editor
})
=>
onChange
(
editor
.
getHTML
()),
onFocus
:
({
editor
})
=>
{
const
wrap
=
editor
.
options
.
element
.
closest
(
'
.atma-editor-wrap
'
)
wrap
.
querySelectorAll
(
'
.atma-editor-toolbar-s
'
).
forEach
(
function
(
s
)
{
...
...
@@ -488,7 +486,7 @@ const QEditor = ({
)
}
const
getUploader
=
({
accept
=
'
*
'
,
...
o
})
=>
{
const
getUploader
=
({
accept
=
'
*
'
,
...
o
})
=>
{
let
url
=
uploadOptions
.
url
let
multiple
=
true
if
(
o
.
afterParams
&&
o
.
afterParams
.
length
>
0
)
{
...
...
@@ -544,12 +542,10 @@ const QEditor = ({
)
data
.
append
(
'
file
'
,
file
)
const
headers
=
{
'
Content-Type
'
:
'
multipart/form-data
'
}
const
headers
=
{
'
Content-Type
'
:
'
multipart/form-data
'
}
return
new
Promise
(
function
(
resolve
)
{
axios
.
post
(
uploadOptions
.
url
,
data
,
{
headers
:
headers
})
.
then
((
response
)
=>
{
axios
.
post
(
uploadOptions
.
url
,
data
,
{
headers
:
headers
}).
then
((
response
)
=>
{
if
(
response
.
data
.
state
===
'
success
'
)
{
resolve
(
response
.
data
)
}
...
...
@@ -587,7 +583,7 @@ const QEditor = ({
)
case
'
audio
'
:
return
(
<
Fragment
>
{
getUploader
({
accept
:
'
.wav, .mp3, .ogg
'
})
}
</
Fragment
>
<
Fragment
>
{
getUploader
({
accept
:
'
.wav, .mp3, .ogg
'
})
}
</
Fragment
>
)
case
'
iframe_pdf
'
:
return
(
...
...
@@ -599,13 +595,13 @@ const QEditor = ({
</
Fragment
>
)
case
'
video
'
:
return
<
Fragment
>
{
getUploader
({
accept
:
'
video/*
'
})
}
</
Fragment
>
return
<
Fragment
>
{
getUploader
({
accept
:
'
video/*
'
})
}
</
Fragment
>
case
'
image
'
:
return
<
Fragment
>
{
getUploader
({
accept
:
'
image/*
'
})
}
</
Fragment
>
return
<
Fragment
>
{
getUploader
({
accept
:
'
image/*
'
})
}
</
Fragment
>
case
'
file
'
:
return
(
<
Fragment
>
{
getUploader
({
accept
:
'
*
'
,
afterParams
:
[
'
no_convert=1
'
]
})
}
{
getUploader
({
accept
:
'
*
'
,
afterParams
:
[
'
no_convert=1
'
]})
}
</
Fragment
>
)
case
'
voicemessage
'
:
...
...
@@ -614,16 +610,16 @@ const QEditor = ({
{
isMobile
&&
(
<
div
className
=
'webwrap'
>
<
div
>
Аудиозапись с мобильного устройства недоступна,
<
br
/>
{
'
'
}
Аудиозапись с мобильного устройства недоступна,
<
br
/>
{
'
'
}
запишите стандартными функциями устройства и воспользуйтесь
кнопкой «Прикрепить файл»
</
div
>
</
div
>
)
}
{
!
isMobile
&&
(
{
!
isMobile
&&
(
<
div
className
=
'audio-player'
>
<
div
className
=
'audio-player-start audio-player-margin'
>
{
status
===
'
recording
'
&&
!
mediaBlobUrl
?
(
{
status
===
'
recording
'
&&
!
mediaBlobUrl
?
(
<
div
onClick
=
{
stopRecording
}
className
=
'audio-player-center-recording'
...
...
@@ -635,13 +631,13 @@ const QEditor = ({
/>
)
}
</
div
>
<
div
className
=
'audio-player-voice audio-player-margin'
/>
{
status
===
'
recording
'
&&
!
mediaBlobUrl
?
(
<
div
className
=
'audio-player-voice audio-player-margin'
/>
{
status
===
'
recording
'
&&
!
mediaBlobUrl
?
(
<
ReactStopwatch
seconds
=
{
0
}
minutes
=
{
0
}
hours
=
{
0
}
render
=
{
({
formatted
})
=>
{
render
=
{
({
formatted
})
=>
{
return
(
<
span
className
=
'audio-player-timer audio-player-margin'
>
{
formatted
}
...
...
@@ -650,7 +646,7 @@ const QEditor = ({
}
}
/>
)
:
(
<
span
className
=
'audio-player-timer audio-player-margin'
/>
<
span
className
=
'audio-player-timer audio-player-margin'
/>
)
}
</
div
>
)
}
...
...
@@ -663,13 +659,13 @@ const QEditor = ({
{
isMobile
&&
(
<
div
className
=
'webwrap'
>
<
div
>
Запись экрана с мобильного устройства недоступна,
<
br
/>
Запись экрана с мобильного устройства недоступна,
<
br
/>
запишите стандартными функциями устройства и воспользуйтесь
кнопкой «Загрузить видео»
</
div
>
</
div
>
)
}
{
!
isMobile
&&
(
{
!
isMobile
&&
(
<>
<
div
className
=
'webwrap'
>
<
div
className
=
'webwrap-content'
>
...
...
@@ -691,12 +687,12 @@ const QEditor = ({
/>
)
)
}
{
status
===
'
recording
'
&&
!
mediaBlobUrl
?
(
{
status
===
'
recording
'
&&
!
mediaBlobUrl
?
(
<
ReactStopwatch
seconds
=
{
0
}
minutes
=
{
0
}
hours
=
{
0
}
render
=
{
({
formatted
})
=>
{
render
=
{
({
formatted
})
=>
{
return
(
<
span
className
=
'webwrap-timer'
>
{
formatted
}
</
span
>
)
...
...
@@ -705,7 +701,7 @@ const QEditor = ({
)
:
(
<
span
className
=
'webwrap-timer'
>
00:00:00
</
span
>
)
}
{
!
mediaBlobUrl
&&
(
{
!
mediaBlobUrl
&&
(
<
div
className
=
'webwrap-start-border'
>
<
button
onClick
=
{
...
...
@@ -726,14 +722,14 @@ const QEditor = ({
<
div
className
=
'web-bottom-elements'
>
{
mediaBlobUrl
&&
(
<
div
onClick
=
{
clearBlobUrl
}
className
=
'web-button-wrap'
>
<
div
className
=
'web-button-rerecord'
/>
<
div
className
=
'web-button-rerecord'
/>
<
span
className
=
'web-button-rerecord-text'
>
Перезаписать
</
span
>
</
div
>
)
}
{
!
mediaBlobUrl
&&
<
div
className
=
'web-button-spacer'
/>
}
{
!
mediaBlobUrl
&&
(
{
!
mediaBlobUrl
&&
<
div
className
=
'web-button-spacer'
/>
}
{
!
mediaBlobUrl
&&
(
<
div
onClick
=
{
isAudioMuted
?
unMuteAudio
:
muteAudio
}
className
=
{
...
...
@@ -741,7 +737,7 @@ const QEditor = ({
}
/>
)
}
<
div
className
=
'web-button-spacer'
/>
<
div
className
=
'web-button-spacer'
/>
</
div
>
</>
)
}
...
...
@@ -755,13 +751,13 @@ const QEditor = ({
{
isMobile
&&
(
<
div
className
=
'webwrap'
>
<
div
>
Видеозапись с мобильного устройства недоступна,
<
br
/>
Видеозапись с мобильного устройства недоступна,
<
br
/>
запишите стандартными функциями устройства и воспользуйтесь
кнопкой «Загрузить видео»
</
div
>
</
div
>
)
}
{
!
isMobile
&&
(
{
!
isMobile
&&
(
<>
<
div
className
=
'webwrap'
>
<
div
className
=
'webwrap-content'
>
...
...
@@ -783,12 +779,12 @@ const QEditor = ({
/>
)
)
}
{
status
===
'
recording
'
&&
!
mediaBlobUrl
?
(
{
status
===
'
recording
'
&&
!
mediaBlobUrl
?
(
<
ReactStopwatch
seconds
=
{
0
}
minutes
=
{
0
}
hours
=
{
0
}
render
=
{
({
formatted
})
=>
{
render
=
{
({
formatted
})
=>
{
return
(
<
span
className
=
'webwrap-timer'
>
{
formatted
}
</
span
>
)
...
...
@@ -797,7 +793,7 @@ const QEditor = ({
)
:
(
<
span
className
=
'webwrap-timer'
>
00:00:00
</
span
>
)
}
{
!
mediaBlobUrl
&&
(
{
!
mediaBlobUrl
&&
(
<
div
className
=
'webwrap-start-border'
>
<
button
onClick
=
{
...
...
@@ -818,14 +814,14 @@ const QEditor = ({
<
div
className
=
'web-bottom-elements'
>
{
mediaBlobUrl
&&
(
<
div
onClick
=
{
clearBlobUrl
}
className
=
'web-button-wrap'
>
<
div
className
=
'web-button-rerecord'
/>
<
div
className
=
'web-button-rerecord'
/>
<
span
className
=
'web-button-rerecord-text'
>
Перезаписать
</
span
>
</
div
>
)
}
{
!
mediaBlobUrl
&&
<
div
className
=
'web-button-spacer'
/>
}
{
!
mediaBlobUrl
&&
(
{
!
mediaBlobUrl
&&
<
div
className
=
'web-button-spacer'
/>
}
{
!
mediaBlobUrl
&&
(
<
div
onClick
=
{
isAudioMuted
?
unMuteAudio
:
muteAudio
}
className
=
{
...
...
@@ -833,7 +829,7 @@ const QEditor = ({
}
/>
)
}
<
div
className
=
'web-button-spacer'
/>
<
div
className
=
'web-button-spacer'
/>
</
div
>
</>
)
}
...
...
@@ -856,17 +852,17 @@ const QEditor = ({
}
break
case
'
screencust
'
:
if
(
status
===
'
recording
'
||
isUploading
||
!
mediaBlobUrl
)
{
if
(
status
===
'
recording
'
||
isUploading
||
!
mediaBlobUrl
)
{
isDisabled
=
true
}
break
case
'
voicemessage
'
:
if
(
status
===
'
recording
'
||
isUploading
||
!
mediaBlobUrl
)
{
if
(
status
===
'
recording
'
||
isUploading
||
!
mediaBlobUrl
)
{
isDisabled
=
true
}
break
case
'
webcamera
'
:
if
(
status
===
'
recording
'
||
isUploading
||
!
mediaBlobUrl
)
{
if
(
status
===
'
recording
'
||
isUploading
||
!
mediaBlobUrl
)
{
isDisabled
=
true
}
break
...
...
@@ -895,14 +891,14 @@ const QEditor = ({
const
regex
=
new
RegExp
(
'
(?:<iframe[^>]*)(?:(?:
\\
/>)|(?:>.*?<
\\
/iframe>))
'
)
isDisabled
=
!
regex
.
test
(
embedContent
)
isDisabled
=
!
regex
.
test
(
embedContent
)
break
}
return
isDisabled
}
if
(
!
editor
)
{
if
(
!
editor
)
{
return
null
}
...
...
@@ -960,12 +956,11 @@ const QEditor = ({
return
false
}
else
{
if
(
document
.
querySelectorAll
(
'
.atma-editor-uploader-progress
'
)
.
length
>
0
document
.
querySelectorAll
(
'
.atma-editor-uploader-progress
'
).
length
>
0
)
{
if
(
// eslint-disable-next-line no-undef
!
confirm
(
!
confirm
(
'
Не полностью загруженные файлы будут утеряны. Вы уверены, что хотите продолжить?
'
)
)
{
...
...
@@ -976,31 +971,23 @@ const QEditor = ({
switch
(
innerModalType
)
{
case
'
image
'
:
uploadedPaths
.
map
((
file
,
i
)
=>
{
editor
.
chain
().
focus
().
setImage
({
src
:
file
.
path
}).
run
();
editor
.
chain
().
focus
().
setImage
({
src
:
file
.
path
}).
run
();
})
break
case
'
video
'
:
uploadedPaths
.
map
((
file
,
i
)
=>
{
editor
.
chain
()
.
focus
()
.
setVideo
({
editor
.
chain
().
focus
().
setVideo
({
src
:
file
.
path
,
poster
:
file
.
path
+
'
.jpg
'
})
.
run
()
}).
run
()
})
break
case
'
voicemessage
'
:
if
(
mediaBlobUrl
&&
uploadedPaths
.
length
===
0
)
{
if
(
!
isUploading
)
{
if
(
!
isUploading
)
{
await
saveScreenCust
(
mediaBlobUrl
).
then
((
data
)
=>
{
if
(
data
?.
file_path
)
{
editor
.
chain
()
.
focus
()
.
addVoiceMessage
({
src
:
data
.
file_path
})
.
run
()
editor
.
chain
().
focus
().
addVoiceMessage
({
src
:
data
.
file_path
}).
run
()
}
})
}
...
...
@@ -1008,14 +995,10 @@ const QEditor = ({
break
case
'
screencust
'
:
if
(
mediaBlobUrl
&&
uploadedPaths
.
length
===
0
)
{
if
(
!
isUploading
)
{
if
(
!
isUploading
)
{
await
saveScreenCust
(
mediaBlobUrl
).
then
((
data
)
=>
{
if
(
data
?.
file_path
)
{
editor
.
chain
()
.
focus
()
.
setVideo
({
src
:
data
.
file_path
})
.
run
()
editor
.
chain
().
focus
().
setVideo
({
src
:
data
.
file_path
}).
run
()
}
})
}
...
...
@@ -1023,14 +1006,10 @@ const QEditor = ({
break
case
'
webcamera
'
:
if
(
mediaBlobUrl
&&
uploadedPaths
.
length
===
0
)
{
if
(
!
isUploading
)
{
if
(
!
isUploading
)
{
await
saveScreenCust
(
mediaBlobUrl
).
then
((
data
)
=>
{
if
(
data
?.
file_path
)
{
editor
.
chain
()
.
focus
()
.
setVideo
({
src
:
data
.
file_path
})
.
run
()
editor
.
chain
().
focus
().
setVideo
({
src
:
data
.
file_path
}).
run
()
}
})
}
...
...
@@ -1043,10 +1022,7 @@ const QEditor = ({
const
url
=
new
URL
(
reg
.
test
(
_url
)
?
_url
:
'
https:
'
+
_url
)
let
urlId
=
url
.
pathname
.
replace
(
/
\/
$/gi
,
''
)
.
split
(
'
/
'
)
.
pop
()
let
urlId
=
url
.
pathname
.
replace
(
/
\/
$/gi
,
''
).
split
(
'
/
'
).
pop
()
switch
(
url
.
hostname
)
{
case
'
rutube.ru
'
:
...
...
@@ -1074,57 +1050,41 @@ const QEditor = ({
_url
=
`https://www.youtube.com/embed/
${
urlId
}
`
break
}
editor
.
chain
().
focus
().
setIframe
({
src
:
_url
}).
run
()
editor
.
chain
().
focus
().
setIframe
({
src
:
_url
}).
run
()
break
case
'
iframe_custom
'
:
editor
.
chain
().
focus
().
insertContent
(
embedContent
).
run
()
break
case
'
iframe_pptx
'
:
uploadedPaths
.
map
((
file
,
i
)
=>
{
editor
.
chain
()
.
focus
()
.
insertContent
(
editor
.
chain
().
focus
().
insertContent
(
`<iframe src="https://view.officeapps.live.com/op/embed.aspx?src=
${
file
.
path
}
" width="100%" height="600px" frameBorder="0"></iframe>`
)
.
run
()
).
run
()
})
break
case
'
audio
'
:
uploadedPaths
.
map
((
file
)
=>
{
editor
.
chain
()
.
focus
()
.
insertContent
(
editor
.
chain
().
focus
().
insertContent
(
`<audio class="audio-player" controls="true" src="
${
file
.
path
}
" />`
)
.
run
()
).
run
()
})
break
case
'
iframe_pdf
'
:
uploadedPaths
.
map
((
file
,
i
)
=>
{
editor
.
chain
()
.
focus
()
.
insertContent
(
editor
.
chain
().
focus
().
insertContent
(
`<iframe src="https://docs.google.com/viewer?embedded=true&url=
${
file
.
path
}
" width="100%" height="800px" frameBorder="0"></iframe>`
)
.
run
()
).
run
()
})
break
case
'
file
'
:
uploadedPaths
.
map
((
file
,
i
)
=>
{
let
exp
=
file
.
path
.
split
(
'
.
'
)
exp
=
exp
[
exp
.
length
-
1
]
editor
.
chain
()
.
focus
()
.
insertContent
(
editor
.
chain
().
focus
().
insertContent
(
`
<a href="
${
file
.
path
}
" target="_blank" download="
${
file
.
name
}
.
${
exp
}
" data-size="
${
file
.
size
}
">
${
file
.
name
}
</a>
`
)
.
run
()
).
run
()
})
break
}
...
...
@@ -1152,11 +1112,11 @@ const QEditor = ({
return
(
<
div
className
=
'atma-editor-wrap'
style
=
{
style
}
>
<
div
className
=
'atma-editor'
>
<
ToolBar
editor
=
{
editor
}
{
...{
toolsOptions
}
}
{
...{
toolsLib
}
}
/>
<
ToolBar
editor
=
{
editor
}
{
...{
toolsOptions
}
}
{
...{
toolsLib
}
}
/>
<
BubbleMenu
typpyOptions
=
{
{
followCursor
:
true
}
}
typpyOptions
=
{
{
followCursor
:
true
}
}
editor
=
{
editor
}
shouldShow
=
{
({
...
o
})
=>
{
shouldShow
=
{
({...
o
})
=>
{
let
items
=
[]
if
(
o
.
from
!==
o
.
to
&&
...
...
@@ -1177,7 +1137,7 @@ const QEditor = ({
return
true
}
}
}
tippyOptions
=
{
{
duration
:
100
}
}
tippyOptions
=
{
{
duration
:
100
}
}
>
<
div
className
=
'atma-editor-bubble'
...
...
@@ -1191,36 +1151,16 @@ const QEditor = ({
className
=
{
'
qcolors
'
+
(
itemColor
===
'
none
'
?
'
unset
'
:
''
)
}
style
=
{
{
background
:
itemColor
}
}
style
=
{
{
background
:
itemColor
}
}
onClick
=
{
()
=>
{
if
(
itemColor
===
'
none
'
)
{
colorsSelected
===
'
color
'
?
editor
.
chain
()
.
focus
()
.
unsetHighlight
()
.
unsetColor
()
.
run
()
:
editor
.
chain
()
.
focus
()
.
unsetColor
()
.
unsetHighlight
()
.
run
()
?
editor
.
chain
().
focus
().
unsetHighlight
().
unsetColor
().
run
()
:
editor
.
chain
().
focus
().
unsetColor
().
unsetHighlight
().
run
()
}
else
{
colorsSelected
===
'
color
'
?
editor
.
chain
()
.
focus
()
.
unsetHighlight
()
.
setColor
(
itemColor
)
.
run
()
:
editor
.
chain
()
.
focus
()
.
unsetColor
()
.
toggleHighlight
({
color
:
itemColor
})
.
run
()
?
editor
.
chain
().
focus
().
unsetHighlight
().
setColor
(
itemColor
).
run
()
:
editor
.
chain
().
focus
().
unsetColor
().
toggleHighlight
({
color
:
itemColor
}).
run
()
}
setColorsSelected
(
null
)
}
}
...
...
@@ -1230,7 +1170,7 @@ const QEditor = ({
:
bubbleItems
.
map
((
type
,
i
)
=>
{
if
(
type
===
'
|
'
)
{
return
(
<
div
key
=
{
'
bubbleSeparator
'
+
i
}
className
=
'qseparator'
/>
<
div
key
=
{
'
bubbleSeparator
'
+
i
}
className
=
'qseparator'
/>
)
}
else
{
return
(
...
...
@@ -1249,7 +1189,7 @@ const QEditor = ({
})
}
</
div
>
</
BubbleMenu
>
<
EditorContent
editor
=
{
editor
}
className
=
'atma-editor-content'
/>
<
EditorContent
editor
=
{
editor
}
className
=
'atma-editor-content'
/>
</
div
>
<
EditorModal
isOpen
=
{
modalIsOpen
}
title
=
{
modalTitle
}
>
{
getInnerModal
()
}
...
...
src/extensions/Resizing.js
View file @
934d6b2b
...
...
@@ -4,7 +4,7 @@ import { Extension } from "@tiptap/core";
export
default
Extension
.
create
({
name
:
"
Resizable
"
,
addOptions
()
{
addOptions
()
{
return
{
types
:
[
"
image
"
,
"
video
"
],
handlerStyle
:
{
...
...
@@ -18,31 +18,31 @@ export default Extension.create({
};
},
addStorage
()
{
addStorage
()
{
return
{
resizeElement
:
null
,
};
},
onCreate
({
editor
})
{
onCreate
({
editor
})
{
const
element
=
editor
.
options
.
element
;
element
.
style
.
position
=
"
relative
"
;
// resizeLayer
console
.
log
(
'
onCreate
'
,
editor
);
const
resizeLayer
=
document
.
createElement
(
"
div
"
);
resizeLayer
.
className
=
"
resize-layer
"
;
resizeLayer
.
style
.
display
=
"
none
"
;
resizeLayer
.
style
.
position
=
"
absolute
"
;
Object
.
entries
(
this
.
options
.
layerStyle
).
forEach
(([
key
,
value
])
=>
{
resizeLayer
.
style
[
key
]
=
value
;
});
resizeLayer
.
addEventListener
(
"
mousedown
"
,
(
e
)
=>
{
const
resizeElement
=
this
.
storage
.
resizeElement
;
if
(
!
resizeElement
)
return
;
if
(
!
resizeElement
)
return
;
if
(
/bottom/
.
test
(
e
.
target
.
className
))
{
let
startX
=
e
.
screenX
;
const
dir
=
e
.
target
.
classList
.
contains
(
"
bottom-left
"
)
?
-
1
:
1
;
...
...
@@ -57,8 +57,6 @@ export default Extension.create({
const
clientHeight
=
resizeElement
.
clientHeight
;
resizeElement
.
style
.
width
=
clientWidth
+
"
px
"
;
// max width
// resizeLayer
const
pos
=
getRelativePosition
(
resizeElement
,
element
);
resizeLayer
.
style
.
top
=
pos
.
top
+
"
px
"
;
...
...
@@ -69,7 +67,7 @@ export default Extension.create({
startX
=
e
.
screenX
;
};
document
.
addEventListener
(
"
mousemove
"
,
mousemoveHandle
);
document
.
addEventListener
(
"
mouseup
"
,
()
=>
{
document
.
addEventListener
(
"
mouseup
"
,
()
=>
{
document
.
removeEventListener
(
"
mousemove
"
,
mousemoveHandle
)
});
}
...
...
@@ -95,60 +93,42 @@ export default Extension.create({
editor
.
resizeLayer
=
resizeLayer
;
element
.
appendChild
(
resizeLayer
);
},
onSelectionUpdate
({
editor
,
transaction
})
{
onUpdate
({
editor
,
transaction
})
{
selectionUpdate
({
editor
,
transaction
},
this
.
options
,
this
.
storage
)
},
onSelectionUpdate
({
editor
,
transaction
})
{
selectionUpdate
({
editor
,
transaction
},
this
.
options
,
this
.
storage
)
},
});
function
selectionUpdate
({
editor
,
transaction
},
options
,
storage
)
{
const
element
=
editor
.
options
.
element
;
const
node
=
transaction
.
curSelection
.
node
;
const
resizeLayer
=
editor
.
resizeLayer
;
console
.
log
(
"
res layer
"
,
resizeLayer
)
if
(
node
&&
this
.
options
.
types
.
includes
(
node
.
type
.
name
))
{
// resizeLayer
位置大小
//
console.log("res layer",
resizeLayer)
if
(
node
&&
options
.
types
.
includes
(
node
.
type
.
name
))
{
// resizeLayer
resizeLayer
.
style
.
display
=
"
block
"
;
let
dom
=
editor
.
view
.
domAtPos
(
transaction
.
curSelection
.
from
).
node
;
if
(
dom
.
getAttribute
(
"
src
"
)
!==
node
.
attrs
.
src
)
{
dom
=
dom
.
querySelector
(
`[src="
${
node
.
attrs
.
src
}
"]`
);
}
this
.
storage
.
resizeElement
=
dom
;
storage
.
resizeElement
=
dom
;
const
pos
=
getRelativePosition
(
dom
,
element
);
console
.
log
(
"
dom after src
"
,
dom
)
console
.
log
(
pos
)
resizeLayer
.
style
.
top
=
pos
.
top
+
"
px
"
;
resizeLayer
.
style
.
left
=
pos
.
left
+
"
px
"
;
resizeLayer
.
style
.
width
=
dom
.
width
+
"
px
"
;
resizeLayer
.
style
.
height
=
dom
.
height
+
"
px
"
;
const
resizeObserver
=
new
ResizeObserver
((
entries
)
=>
{
for
(
let
entry
of
entries
)
{
const
currentPosition
=
entry
.
target
.
getBoundingClientRect
();
if
(
currentPosition
.
x
===
0
)
{
console
.
log
(
"
changed pos
"
);
//resizeLayer.style.display = "none";
}
console
.
log
(
entry
.
target
.
parentNode
)
console
.
log
(
"
target:
"
,
entry
.
target
)
console
.
log
(
"
bounding rect:
"
,
currentPosition
)
}
})
resizeObserver
.
observe
(
dom
);
}
else
{
console
.
log
(
"
no node
"
);
resizeLayer
.
style
.
display
=
"
none
"
;
}
},
});
// 计算相对位置
function
getRelativePosition
(
element
,
ancestor
)
{
}
function
getRelativePosition
(
element
,
ancestor
)
{
const
elementRect
=
element
.
getBoundingClientRect
();
const
ancestorRect
=
ancestor
.
getBoundingClientRect
();
const
relativePosition
=
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment