@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
141 lines (139 loc) • 3.71 kB
JavaScript
import { roundToNearest } from '../media-single';
import { getMediaSingleDimensions } from './utils';
const RELATIVE_GUIDES_GAP = 6;
const getWidthRelativeGuideline = (key, view, nodeWithPos, editorWidth, topOffset, size) => {
const {
node,
pos
} = nodeWithPos;
const {
height: viewHeight
} = view.dom.getBoundingClientRect();
const {
top
} = view.coordsAtPos(pos + 1); // media node
const {
width,
height
} = size || getMediaSingleDimensions(node, editorWidth) || {};
const y = top - topOffset - RELATIVE_GUIDES_GAP;
if (!width || !height || y < 0 || y > viewHeight) {
return null;
}
let start = 0;
let end = 0;
switch (node.attrs.layout) {
case 'align-start':
case 'wrap-left':
start = -editorWidth / 2;
end = start + width;
break;
case 'align-end':
case 'wrap-right':
end = editorWidth / 2;
start = end - width;
break;
case 'center':
case 'wide':
case 'full-width':
end = width / 2;
start = -end;
break;
default:
}
return {
key,
position: {
y,
x: {
start,
end
}
},
active: true,
styles: {
lineStyle: 'dashed',
capStyle: 'line'
}
};
};
const getHeightRelativeGuideline = (key, view, nodeWithPos, editorWidth, topOffset, size) => {
const {
node,
pos
} = nodeWithPos;
const {
height: viewHeight
} = view.dom.getBoundingClientRect();
const {
top
} = view.coordsAtPos(pos + 1); // media node
const {
width,
height
} = size || getMediaSingleDimensions(node, editorWidth) || {};
if (!width || !height) {
return null;
}
const start = top - topOffset;
const end = start + height;
if (end < 0 || start > viewHeight) {
return null;
}
let x = 0;
const halfWidth = editorWidth / 2;
switch (node.attrs.layout) {
case 'align-start':
case 'wrap-left':
x = width - halfWidth;
break;
case 'align-end':
case 'wrap-right':
x = halfWidth;
break;
case 'center':
case 'wide':
case 'full-width':
x = width / 2;
break;
default:
x = 0;
}
return {
key,
position: {
x: x + RELATIVE_GUIDES_GAP,
y: {
start,
end
}
},
active: true,
styles: {
lineStyle: 'dashed',
capStyle: 'line'
}
};
};
export const getRelativeGuideSnaps = (relativeGuides, aspectRatio) => {
const snapsWidthFromMatchingHeight = Object.keys(relativeGuides.height || {}).map(heightKey => {
const height = Number.parseInt(heightKey);
return roundToNearest(height * aspectRatio);
});
const snapsWidthFromMatchingWidth = Object.keys(relativeGuides.width || {}).map(widthKey => {
return Number.parseInt(widthKey);
});
return [...snapsWidthFromMatchingWidth, ...snapsWidthFromMatchingHeight];
};
export const getRelativeGuidelines = (relativeGuides, nodeWithPos, view, editorWidth, topOffset, size) => {
const matchWidth = relativeGuides.width ? relativeGuides.width[Math.round(size.width)] : [];
const matchHeight = relativeGuides.height ? relativeGuides.height[Math.round(size.height)] : [];
const matches = matchWidth || matchHeight;
const getRelativeGuideline = matchWidth && getWidthRelativeGuideline || matchHeight && getHeightRelativeGuideline || null;
if (matches && getRelativeGuideline) {
return [getRelativeGuideline('relative_guide_current', view, nodeWithPos, editorWidth, topOffset, size), ...matches.map((nodeWithPos, index) => {
return getRelativeGuideline(`relative_guide_${index}`, view, nodeWithPos, editorWidth, topOffset);
})].filter(config => !!config);
}
return [];
};