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
a24ab44a
Commit
a24ab44a
authored
Aug 29, 2026
by
Яков
Browse files
update
parent
408df449
Changes
2
Hide whitespace changes
Inline
Side-by-side
package.json
View file @
a24ab44a
{
"name"
:
"react-ag-qeditor"
,
"version"
:
"1.1.8
1
"
,
"description"
:
"WYSIWYG html editor"
,
"author"
:
"atma"
,
"license"
:
"
MIT
"
,
"repository"
:
{
"type"
:
"git"
,
"url"
:
"
https://gitlab.atma.company/lib/react-ag-qeditor.git
"
},
"main"
:
"dist/index.js"
,
"module"
:
"dist/index.modern.js"
,
"source"
:
"src/index.js"
,
"engines"
:
{
"node"
:
">=18"
},
"scripts"
:
{
"build"
:
"microbundle-crl --no-compress --format modern,cjs --css-modules false"
,
"start"
:
"microbundle-crl watch --no-compress --format modern,cjs --css-modules false"
,
"prepare"
:
"run-s build"
,
"test"
:
"run-s test:unit test:lint test:build"
,
"test:build"
:
"run-s build"
,
"test:lint"
:
"eslint ."
,
"test:unit"
:
"cross-env CI=1 react-scripts test --env=jsdom"
,
"test:watch"
:
"react-scripts test --env=jsdom"
,
"predeploy"
:
"cd example && npm install && npm run build"
,
"deploy"
:
"gh-pages -d example/build"
,
"start:both"
:
"concurrently
\"
npm start
\"
\"
cd example && npm start
\"
"
},
"peerDependencies"
:
{
"@tiptap/extension-table"
:
"
^2.11.7
"
,
"@tiptap/pm"
:
"^2.11.7"
,
"prosemirror-tables"
:
"
^1.4.0
"
,
"react"
:
"^17.0.2"
,
"react-dom"
:
"^17.0.2"
},
"devDependencies"
:
{
"
@babel/core
"
:
"
7.27.1
"
,
"
@babel/plugin-syntax-object-rest-spread
"
:
"
7.8.3
"
,
"
@babel/preset-env
"
:
"
7.27.1
"
,
"
babel-eslint
"
:
"
^10.0.3
"
,
"
babel-loader
"
:
"
^10.0.0
"
,
"
concurrently
"
:
"
^8.2.1
"
,
"
cross-env
"
:
"
^7.0.2
"
,
"
eslint
"
:
"
^6.8.0
"
,
"
eslint-config-prettier
"
:
"
^6.7.0
"
,
"
eslint-config-standard
"
:
"
^14.1.0
"
,
"
eslint-config-standard-react
"
:
"
^9.2.0
"
,
"
eslint-plugin-import
"
:
"
^2.18.2
"
,
"
eslint-plugin-node
"
:
"
^11.0.0
"
,
"
eslint-plugin-prettier
"
:
"
^3.1.1
"
,
"
eslint-plugin-promise
"
:
"
^4.2.1
"
,
"
eslint-plugin-react
"
:
"
^7.17.0
"
,
"
eslint-plugin-standard
"
:
"
^4.0.1
"
,
"
gh-pages
"
:
"
^2.2.0
"
,
"
microbundle-crl
"
:
"
0.13.11
"
,
"
npm-run-all
"
:
"
4.1.5
"
,
"
prettier
"
:
"
^2.0.4
"
,
"
prosemirror-history
"
:
"
^1.4.1
"
,
"
prosemirror-model
"
:
"
^1.25.1
"
,
"
prosemirror-tables
"
:
"
^1.7.1
"
,
"
prosemirror-transform
"
:
"
^1.10.4
"
,
"
prosemirror-utils
"
:
"
^1.2.2
"
,
"
prosemirror-view
"
:
"
^1.39.2
"
,
"
react-scripts
"
:
"
^5.0.1
"
,
"
webpack
"
:
"
4.42.0
"
},
"files"
:
[
"dist"
],
"dependencies"
:
{
"
@ant-design/icons
"
:
"
^6.0.0
"
,
"
@babel/helper-environment-visitor
"
:
"
^7.24.7
"
,
"
@babel/plugin-proposal-unicode-property-regex
"
:
"
^7.18.6
"
,
"
@tiptap/core
"
:
"
^2.12.0
"
,
"
@tiptap/extension-color
"
:
"
^2.0.0-beta.9
"
,
"
@tiptap/extension-document
"
:
"
^2.12.0
"
,
"
@tiptap/extension-focus
"
:
"
^2.0.0-beta.43
"
,
"
@tiptap/extension-highlight
"
:
"
^2.0.0-beta.33
"
,
"
@tiptap/extension-image
"
:
"
^2.0.0-beta.27
"
,
"
@tiptap/extension-link
"
:
"
^2.0.0-beta.38
"
,
"
@tiptap/extension-paragraph
"
:
"
^2.12.0
"
,
"
@tiptap/extension-subscript
"
:
"
^2.1.11
"
,
"
@tiptap/extension-superscript
"
:
"
^2.1.11
"
,
"
@tiptap/extension-table
"
:
"
^2.0.0-beta.49
"
,
"
@tiptap/extension-table-cell
"
:
"
^2.0.0-beta.20
"
,
"
@tiptap/extension-table-header
"
:
"
^2.0.0-beta.22
"
,
"
@tiptap/extension-table-row
"
:
"
^2.0.0-beta.19
"
,
"
@tiptap/extension-text
"
:
"
^2.12.0
"
,
"
@tiptap/extension-text-align
"
:
"
^2.0.0-beta.29
"
,
"
@tiptap/extension-text-style
"
:
"
^2.0.0-beta.23
"
,
"
@tiptap/extension-underline
"
:
"
^2.0.0-beta.23
"
,
"
@tiptap/react
"
:
"
^2.12.0
"
,
"
@tiptap/starter-kit
"
:
"
^2.0.0-beta.185
"
,
"
antd
"
:
"
^5.24.7
"
,
"
axios
"
:
"
^0.27.2
"
,
"
babel-loader
"
:
"
8.1.0
"
,
"
emojibase-data
"
:
"
^16.0.3
"
,
"
invariant
"
:
"
^2.2.4
"
,
"
katex
"
:
"
^0.15.3
"
,
"
levenary
"
:
"
^1.1.1
"
,
"
prosemirror-state
"
:
"
^1.4.3
"
,
"
rc-upload
"
:
"
^4.3.3
"
,
"
react-device-detect
"
:
"
^2.2.3
"
,
"
react-media-recorder
"
:
"
^1.6.6
"
,
"
react-stopwatch
"
:
"
^2.0.4
"
,
"
react-webcam
"
:
"
^7.0.1
"
,
"
sass
"
:
"
^1.49.9
"
,
"
tiptap-extension-resize-image
"
:
"
^1.1.8
"
,
"
tiptap-imagresize
"
:
"
^1.1.0
"
},
"resolutions"
:
{
"prosemirror-tables"
:
"
1.4.0
"
,
"@tiptap/pm"
:
"2.11.7"
,
"@tiptap/extension-table"
:
"
2.11.7
"
}
"name"
:
"react-ag-qeditor"
,
"version"
:
"1.1.8
2
"
,
"description"
:
"WYSIWYG html editor"
,
"author"
:
"atma"
,
"license"
:
"
MIT
"
,
"repository"
:
{
"type"
:
"git"
,
"url"
:
"
https://gitlab.atma.company/lib/react-ag-qeditor.git
"
},
"main"
:
"dist/index.js"
,
"module"
:
"dist/index.modern.js"
,
"source"
:
"src/index.js"
,
"engines"
:
{
"node"
:
">=18"
},
"scripts"
:
{
"build"
:
"microbundle-crl --no-compress --format modern,cjs --css-modules false"
,
"start"
:
"microbundle-crl watch --no-compress --format modern,cjs --css-modules false"
,
"prepare"
:
"run-s build"
,
"test"
:
"run-s test:unit test:lint test:build"
,
"test:build"
:
"run-s build"
,
"test:lint"
:
"eslint ."
,
"test:unit"
:
"cross-env CI=1 react-scripts test --env=jsdom"
,
"test:watch"
:
"react-scripts test --env=jsdom"
,
"predeploy"
:
"cd example && npm install && npm run build"
,
"deploy"
:
"gh-pages -d example/build"
,
"start:both"
:
"concurrently
\"
npm start
\"
\"
cd example && npm start
\"
"
},
"peerDependencies"
:
{
"@tiptap/extension-table"
:
"
^2.11.7
"
,
"@tiptap/pm"
:
"^2.11.7"
,
"prosemirror-tables"
:
"
^1.4.0
"
,
"react"
:
"^17.0.2"
,
"react-dom"
:
"^17.0.2"
},
"devDependencies"
:
{
"
@babel/core
"
:
"
7.27.1
"
,
"
@babel/plugin-syntax-object-rest-spread
"
:
"
7.8.3
"
,
"
@babel/preset-env
"
:
"
7.27.1
"
,
"
babel-eslint
"
:
"
^10.0.3
"
,
"
babel-loader
"
:
"
^10.0.0
"
,
"
concurrently
"
:
"
^8.2.1
"
,
"
cross-env
"
:
"
^7.0.2
"
,
"
eslint
"
:
"
^6.8.0
"
,
"
eslint-config-prettier
"
:
"
^6.7.0
"
,
"
eslint-config-standard
"
:
"
^14.1.0
"
,
"
eslint-config-standard-react
"
:
"
^9.2.0
"
,
"
eslint-plugin-import
"
:
"
^2.18.2
"
,
"
eslint-plugin-node
"
:
"
^11.0.0
"
,
"
eslint-plugin-prettier
"
:
"
^3.1.1
"
,
"
eslint-plugin-promise
"
:
"
^4.2.1
"
,
"
eslint-plugin-react
"
:
"
^7.17.0
"
,
"
eslint-plugin-standard
"
:
"
^4.0.1
"
,
"
gh-pages
"
:
"
^2.2.0
"
,
"
microbundle-crl
"
:
"
0.13.11
"
,
"
npm-run-all
"
:
"
4.1.5
"
,
"
prettier
"
:
"
^2.0.4
"
,
"
prosemirror-history
"
:
"
^1.4.1
"
,
"
prosemirror-model
"
:
"
^1.25.1
"
,
"
prosemirror-tables
"
:
"
^1.7.1
"
,
"
prosemirror-transform
"
:
"
^1.10.4
"
,
"
prosemirror-utils
"
:
"
^1.2.2
"
,
"
prosemirror-view
"
:
"
^1.39.2
"
,
"
react-scripts
"
:
"
^5.0.1
"
,
"
webpack
"
:
"
4.42.0
"
},
"files"
:
[
"dist"
],
"dependencies"
:
{
"
@ant-design/icons
"
:
"
^6.0.0
"
,
"
@babel/helper-environment-visitor
"
:
"
^7.24.7
"
,
"
@babel/plugin-proposal-unicode-property-regex
"
:
"
^7.18.6
"
,
"
@tiptap/core
"
:
"
^2.12.0
"
,
"
@tiptap/extension-color
"
:
"
^2.0.0-beta.9
"
,
"
@tiptap/extension-document
"
:
"
^2.12.0
"
,
"
@tiptap/extension-focus
"
:
"
^2.0.0-beta.43
"
,
"
@tiptap/extension-highlight
"
:
"
^2.0.0-beta.33
"
,
"
@tiptap/extension-image
"
:
"
^2.0.0-beta.27
"
,
"
@tiptap/extension-link
"
:
"
^2.0.0-beta.38
"
,
"
@tiptap/extension-paragraph
"
:
"
^2.12.0
"
,
"
@tiptap/extension-subscript
"
:
"
^2.1.11
"
,
"
@tiptap/extension-superscript
"
:
"
^2.1.11
"
,
"
@tiptap/extension-table
"
:
"
^2.0.0-beta.49
"
,
"
@tiptap/extension-table-cell
"
:
"
^2.0.0-beta.20
"
,
"
@tiptap/extension-table-header
"
:
"
^2.0.0-beta.22
"
,
"
@tiptap/extension-table-row
"
:
"
^2.0.0-beta.19
"
,
"
@tiptap/extension-text
"
:
"
^2.12.0
"
,
"
@tiptap/extension-text-align
"
:
"
^2.0.0-beta.29
"
,
"
@tiptap/extension-text-style
"
:
"
^2.0.0-beta.23
"
,
"
@tiptap/extension-underline
"
:
"
^2.0.0-beta.23
"
,
"
@tiptap/react
"
:
"
^2.12.0
"
,
"
@tiptap/starter-kit
"
:
"
^2.0.0-beta.185
"
,
"
antd
"
:
"
^5.24.7
"
,
"
axios
"
:
"
^0.27.2
"
,
"
babel-loader
"
:
"
8.1.0
"
,
"
emojibase-data
"
:
"
^16.0.3
"
,
"
invariant
"
:
"
^2.2.4
"
,
"
katex
"
:
"
^0.15.3
"
,
"
levenary
"
:
"
^1.1.1
"
,
"
prosemirror-state
"
:
"
^1.4.3
"
,
"
rc-upload
"
:
"
^4.3.3
"
,
"
react-device-detect
"
:
"
^2.2.3
"
,
"
react-media-recorder
"
:
"
^1.6.6
"
,
"
react-stopwatch
"
:
"
^2.0.4
"
,
"
react-webcam
"
:
"
^7.0.1
"
,
"
sass
"
:
"
^1.49.9
"
,
"
tiptap-extension-resize-image
"
:
"
^1.1.8
"
,
"
tiptap-imagresize
"
:
"
^1.1.0
"
},
"resolutions"
:
{
"prosemirror-tables"
:
"
1.4.0
"
,
"@tiptap/pm"
:
"2.11.7"
,
"@tiptap/extension-table"
:
"
2.11.7
"
}
}
src/extensions/Iframe.js
View file @
a24ab44a
...
...
@@ -319,10 +319,64 @@ const ResizableIframeView = ({ editor, node, updateAttributes, getPos, selected
<
/Fragment
>
)}
<
/div
>
{
/*
Досмотр настраивается только у выделенной вставки и только там,
где его можно измерить: YouTube, ВКонтакте, Rutube отдают
позицию воспроизведения, а документ Google или произвольная
страница — нет. Показывать там «досмотреть до 80%» значило бы
обещать проверку, которой не будет.
*/
}
{
selected
&&
MEASURABLE
.
test
(
node
.
attrs
.
src
||
''
)
&&
(
<
div
className
=
"
atma-video-watch
"
contentEditable
=
{
false
}
>
<
label
>
<
input
type
=
"
checkbox
"
checked
=
{
node
.
attrs
.
threshold
!=
null
}
onChange
=
{(
e
)
=>
updateAttributes
({
threshold
:
e
.
target
.
checked
?
80
:
null
})
}
/
>
досмотреть
до
<
/label
>
<
input
type
=
"
number
"
min
=
{
1
}
max
=
{
100
}
disabled
=
{
node
.
attrs
.
threshold
==
null
}
value
=
{
node
.
attrs
.
threshold
==
null
?
80
:
node
.
attrs
.
threshold
}
onChange
=
{(
e
)
=>
{
const
v
=
parseInt
(
e
.
target
.
value
,
10
)
updateAttributes
({
threshold
:
Number
.
isFinite
(
v
)
?
Math
.
min
(
100
,
Math
.
max
(
1
,
v
))
:
80
,
})
}}
/
>
<
span
>%<
/span
>
<
label
>
<
input
type
=
"
checkbox
"
checked
=
{
!!
node
.
attrs
.
required
}
onChange
=
{(
e
)
=>
updateAttributes
({
required
:
e
.
target
.
checked
})}
/
>
обязательное
<
/label
>
<
/div
>
)}
<
/NodeViewWrapper
>
)
}
/**
* Вставки, у которых досмотр измерим.
*
* Правило-близнец живёт на стороне платформы (`VideoEmbed.php` и
* `videoEmbed.js`) — там оно полное и по нему собирается разметка. Здесь
* нужно ответить только на вопрос «показывать ли автору настройку», поэтому
* достаточно узнать сервис по адресу.
*/
const
MEASURABLE
=
/^https
?
:
\/\/(
www
\.)?(
youtube
\.
com
\/
embed
\/
|youtube-nocookie
\.
com
\/
embed
\/
|vk
\.
com
\/
video_ext
\.
php|vkvideo
\.
ru
\/
video_ext
\.
php|rutube
\.
ru
\/
play
\/
embed
\/)
/i
const
Iframe
=
Node
.
create
({
name
:
'
iframe
'
,
group
:
'
block
'
,
...
...
@@ -365,6 +419,38 @@ const Iframe = Node.create({
parseHTML
:
(
el
)
=>
el
.
getAttribute
(
'
data-node-id
'
),
renderHTML
:
(
attrs
)
=>
({
'
data-node-id
'
:
attrs
[
'
data-node-id
'
]
}),
},
/**
* Порог обязательного досмотра, проценты.
*
* Работает у YouTube, ВКонтакте и Rutube: их плееры сами сообщают
* позицию воспроизведения. У прочих вставок (документ Google,
* презентация, произвольная страница) измерять нечего — там порог
* автору не показывается.
*
* Считается сумма фактически проигранных отрезков, а не позиция
* ползунка: перемотал в конец — досмотра нет.
*
* null — порога нет. По умолчанию именно так: включённый задним
* числом порог закрыл бы ролики у тех, кто модуль давно прошёл.
*/
threshold
:
{
default
:
null
,
parseHTML
:
(
el
)
=>
{
const
v
=
parseInt
(
el
.
getAttribute
(
'
data-threshold
'
)
||
''
,
10
)
return
Number
.
isFinite
(
v
)
?
Math
.
min
(
100
,
Math
.
max
(
1
,
v
))
:
null
},
renderHTML
:
(
attrs
)
=>
(
attrs
.
threshold
?
{
'
data-threshold
'
:
String
(
attrs
.
threshold
)
}
:
{}),
},
/** Обязательный блок: без него модуль не считается освоенным */
required
:
{
default
:
false
,
parseHTML
:
(
el
)
=>
el
.
getAttribute
(
'
data-required
'
)
===
'
true
'
,
renderHTML
:
(
attrs
)
=>
(
attrs
.
required
?
{
'
data-required
'
:
'
true
'
}
:
{}),
},
}
},
...
...
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