Commit bb440fff authored by Яков's avatar Яков
Browse files

update

parent b5e1ee2c
......@@ -374,9 +374,8 @@ const Iframe = Node.create({
renderHTML({ node, HTMLAttributes }) {
const align = node.attrs.align || 'left'
const style = getStyleForAlign(align)
if (node.attrs.width) style.push(`width: ${node.attrs.width}px`)
if (node.attrs.height) style.push(`height: ${node.attrs.height}px`)
// Инлайновых стилей нет: размеры едут атрибутами width/height, раскладку
// задаёт data-align через CSS платформы. Подробности — в Image.jsx.
return [
'iframe',
......@@ -385,7 +384,8 @@ const Iframe = Node.create({
allow: 'fullscreen',
frameborder: node.attrs.frameborder ?? 0,
'data-align': align,
style: style.join('; '),
width: node.attrs.width || undefined,
height: node.attrs.height || undefined,
}),
]
},
......
......@@ -206,8 +206,17 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
const initImageSize = () => {
try {
// Если размеры уже заданы в атрибутах - используем их сразу
if (node.attrs.width && node.attrs.height) {
// Ширина задана автором — уважаем её и ничего не пересчитываем.
//
// Раньше проверялись ОБЕ величины (width && height). Но в сохранённых
// уроках height есть далеко не всегда: по боевой базе width="N" стоит
// в 305 уроках, а height — в 79. Для остальных условие не срабатывало,
// и картинка при открытии урока молча получала натуральный размер
// вместо авторского: в базе width="1000", в редакторе 80 px.
// Дальше это уезжало в базу при первом же сохранении.
//
// Высота не нужна: она выводится из пропорций (height: auto).
if (node.attrs.width) {
isInitialized.current = true;
return;
}
......@@ -243,8 +252,11 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
};
const handleLoad = () => {
// Если размеры уже заданы в атрибутах, пропускаем инициализацию
if (node.attrs.width && node.attrs.height) {
// Достаточно одной ширины — высота выводится из пропорций.
// Условие «width && height» пропускало картинки, у которых сохранён
// только width (в боевой базе таких большинство: 305 уроков против 79),
// и они получали натуральный размер вместо авторского. См. initImageSize.
if (node.attrs.width) {
isInitialized.current = true;
return;
}
......@@ -378,9 +390,17 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
};
// Внешняя обёртка (NodeViewWrapper): управляет float/block-layout и отступами
// width: min(Npx, 100%) вместо Npx — намеренно.
//
// Фиксированная пиксельная ширина на обёртке делает её минимально-содержимым
// блоком: в узком контейнере (ячейка таблицы) она не даёт ячейке ужаться,
// и таблица растягивается — замерено 1495 px внутри контейнера на 832 px.
// У учащегося тот же <img> с max-width: 100% спокойно ужимается до 229 px,
// и вид расходится. min() сохраняет ширину, заданную автором, и при этом
// позволяет сжаться. Проверяется docs/stand/media-parity.js.
const getOuterStyle = () => {
const { align, wrap, width } = node.attrs;
const w = width ? `${width}px` : 'auto';
const w = width ? `min(${width}px, 100%)` : 'auto';
const sharedMargin = { marginTop: '0.5rem', marginBottom: '0.5rem' };
const noSelect = { userSelect: 'none', WebkitUserSelect: 'none', touchAction: 'manipulation' };
......@@ -415,7 +435,7 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
// Внутренний контейнер: всегда inline-block — надёжно получает высоту от дочернего img
const getInnerStyle = () => {
const { align, width } = node.attrs;
const w = width ? `${width}px` : 'auto';
const w = width ? `min(${width}px, 100%)` : 'auto';
const base = {
position: 'relative',
display: 'inline-block',
......@@ -429,7 +449,7 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
};
if (align === 'center') {
return { ...base, display: 'block', marginLeft: 'auto', marginRight: 'auto',
width: width ? `${width}px` : 'fit-content' };
width: width ? `min(${width}px, 100%)` : 'fit-content' };
}
return base;
};
......@@ -446,7 +466,7 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
// Стили для самого изображения
const getImageStyle = () => ({
width: node.attrs.width ? `${node.attrs.width}px` : 'auto',
width: node.attrs.width ? `min(${node.attrs.width}px, 100%)` : 'auto',
height: 'auto',
maxWidth: '100%',
display: 'block',
......@@ -745,23 +765,17 @@ const ResizableImageExtension = TipTapImage.extend({
const align = node.attrs.align || 'left';
const wrap = node.attrs.wrap || false;
const style = [];
if (align === 'center') {
style.push('display: block', 'margin-left: auto', 'margin-right: auto');
} else if (align === 'left') {
wrap
? style.push('float: left', 'margin-right: 1rem')
: style.push('display: block', 'margin-right: auto');
} else if (align === 'right') {
wrap
? style.push('float: right', 'margin-left: 1rem')
: style.push('display: block', 'margin-left: auto');
}
if (width) style.push(`width: ${width}px`);
if (height) style.push(`height: ${height}px`);
// Инлайновых стилей здесь БОЛЬШЕ НЕТ — намеренно.
//
// Раньше сюда писались 'width: 640px; height: 480px; float: left'. Из-за
// пиксельной высоты картинка искажалась при сужении окна (замерено 26% на
// 768 px и 42% на 600 px), а перебить инлайн из таблицы стилей можно было
// только через !important.
//
// Теперь размеры едут обычными атрибутами width/height: браузер выводит из
// них соотношение сторон, и height: auto в CSS работает без искажений.
// Раскладку задают data-align и data-wrap — правила в
// AtmaGuru/src/React/sass/_content.scss. См. §6.1 ТЗ.
return [
'img',
{
......@@ -771,7 +785,7 @@ const ResizableImageExtension = TipTapImage.extend({
width,
height,
'data-align': align,
style: style.join('; '),
...(wrap ? { 'data-wrap': 'true' } : {}),
...rest,
}
];
......
......@@ -703,29 +703,15 @@ export const InteractiveImage = Node.create({
const align = node.attrs.align || 'left';
const wrap = node.attrs.wrap || false;
const points = node.attrs.points || [];
const style = [];
if (align === 'center') {
style.push('display: block', 'margin-left: auto', 'margin-right: auto');
} else if (align === 'left') {
wrap
? style.push('float: left', 'margin-right: 1rem')
: style.push('display: block', 'margin-right: auto');
} else if (align === 'right') {
wrap
? style.push('float: right', 'margin-left: 1rem')
: style.push('display: block', 'margin-left: auto');
}
if (width) style.push(`width: ${width}px`, 'max-width: 100%');
// Инлайновых стилей нет: размеры едут атрибутами, раскладку задают
// data-align/data-wrap через CSS платформы. Подробности — в Image.jsx.
return [
'interactive-image',
{
src,
width,
height,
style: style.join('; '),
'data-align': align,
'data-wrap': wrap ? 'true' : undefined,
'data-points': JSON.stringify(points),
......
......@@ -376,16 +376,16 @@ const Video = Node.create({
renderHTML({ node, HTMLAttributes }) {
const align = node.attrs.align || 'left'
const style = getStyleForAlign(align)
if (node.attrs.width) style.push(`width: ${node.attrs.width}px`)
if (node.attrs.height) style.push(`height: ${node.attrs.height}px`)
// Инлайновых стилей нет: размеры едут атрибутами width/height, раскладку
// задаёт data-align через CSS платформы. Подробности — в Image.jsx.
return [
'video',
mergeAttributes(HTMLAttributes, {
controls: node.attrs.controls !== false ? 1 : null,
'data-align': align,
style: style.join('; '),
width: node.attrs.width || undefined,
height: node.attrs.height || undefined,
}),
]
},
......
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