Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions packages/super-editor/src/components/toolbar/super-toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,17 @@ export class SuperToolbar extends EventEmitter {
},

setColor: ({ item, argument }) => {
this.#runCommandWithArgumentOnly({ item, argument });
this.#runCommandWithArgumentOnly({ item, argument }, () => {
this.activeEditor?.commands.setFieldAnnotationsTextColor(argument, true);
});
},

setHighlight: ({ item, argument }) => {
this.#runCommandWithArgumentOnly({ item, argument });
this.#runCommandWithArgumentOnly({ item, argument, noArgumentCallback: true }, () => {
let arg = argument !== 'none' ? argument : null;
this.activeEditor?.commands.setFieldAnnotationsTextHighlight(arg, true);
this.activeEditor?.commands.setCellBackground(arg);
});
},

toggleRuler: ({ item, argument }) => {
Expand Down Expand Up @@ -461,14 +467,15 @@ export class SuperToolbar extends EventEmitter {
}
}

#runCommandWithArgumentOnly({ item, argument }, callback) {
#runCommandWithArgumentOnly({ item, argument, noArgumentCallback = false }, callback) {
if (!argument || !this.activeEditor) return;

let command = item.command;
const noArgumentCommand = item.noArgumentCommand;

if (argument === 'none' && noArgumentCommand in this.activeEditor?.commands) {
this.activeEditor.commands[noArgumentCommand]();
if (typeof callback === 'function' && noArgumentCallback) callback(argument);
this.updateToolbarState();
return;
}
Expand Down
18 changes: 18 additions & 0 deletions packages/super-editor/src/core/helpers/getActiveFormatting.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,26 @@ export function getActiveFormatting(editor) {
marksToProcess.push({ name: key, attrs });
});

// For fieldAnnotation.
const textColor = marksToProcess.find((i) => i.name === 'textColor');
const textHightlight = marksToProcess.find((i) => i.name === 'textHighlight');

if (textColor) {
marksToProcess.push({
name: 'color',
attrs: { color: textColor.attrs?.textColor },
});
}
if (textHightlight) {
marksToProcess.push({
name: 'highlight',
attrs: { color: textHightlight.attrs?.textHighlight },
});
}

const hasPendingFormatting = !!editor.storage.formatCommands?.storedStyle;
if (hasPendingFormatting) marksToProcess.push({ name: 'copyFormat', attrs: true });

return marksToProcess;
}

Expand Down
51 changes: 39 additions & 12 deletions packages/super-editor/src/core/super-converter/exporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -1830,6 +1830,8 @@ const translateFieldAttrsToMarks = (attrs = {}) => {
bold,
underline,
italic,
textColor,
textHighlight,
} = attrs;

const marks = [];
Expand All @@ -1838,6 +1840,8 @@ const translateFieldAttrsToMarks = (attrs = {}) => {
if (bold) marks.push({ type: 'bold', attrs: {} });
if (underline) marks.push({ type: 'underline', attrs: {} });
if (italic) marks.push({ type: 'italic', attrs: {} });
if (textColor) marks.push({ type: 'color', attrs: { color: textColor } });
if (textHighlight) marks.push({ type: 'highlight', attrs: { color: textHighlight } });
return marks;
};

Expand Down Expand Up @@ -1918,6 +1922,20 @@ function translateFieldAnnotation(params) {
'w:val': attrs.fontSize,
},
},
{
name: 'w:fieldTextColor',
attributes: {
'xmlns:w': customXmlns,
'w:val': attrs.textColor,
},
},
{
name: 'w:fieldTextHighlight',
attributes: {
'xmlns:w': customXmlns,
'w:val': attrs.textHighlight,
},
},
],
},
{
Expand Down Expand Up @@ -2128,7 +2146,7 @@ function resizeKeepAspectRatio(width, height, maxWidth) {

function applyMarksToHtmlAnnotation(state, marks) {
const { tr, doc, schema } = state;
const allowedMarks = ['fontFamily', 'fontSize'];
const allowedMarks = ['fontFamily', 'fontSize', 'highlight'];

if (
!marks.some((m) => allowedMarks.includes(m.type))
Expand All @@ -2138,32 +2156,41 @@ function applyMarksToHtmlAnnotation(state, marks) {

const fontFamily = marks.find((m) => m.type === 'fontFamily');
const fontSize = marks.find((m) => m.type === 'fontSize');
const highlight = marks.find((m) => m.type === 'highlight');

const textStyleType = schema.marks.textStyle;
const highlightType = schema.marks.highlight;

doc.descendants((node, pos) => {
if (!node.isText) return;

const found = node.marks.find((m) => m.type.name === 'textStyle');
const textStyleType = schema.marks.textStyle;

if (!found) {
const foundTextStyle = node.marks.find((m) => m.type.name === 'textStyle');
const foundHighlight = node.marks.find((m) => m.type.name === 'highlight');

// text style (fontFamily, fontSize)
if (!foundTextStyle) {
tr.addMark(pos, pos + node.nodeSize, textStyleType.create({
...fontFamily?.attrs,
...fontSize?.attrs,
}));
return;
}

if (!found?.attrs.fontFamily && fontFamily) {
} else if (!foundTextStyle?.attrs.fontFamily && fontFamily) {
tr.addMark(pos, pos + node.nodeSize, textStyleType.create({
...found?.attrs,
...foundTextStyle?.attrs,
...fontFamily.attrs,
}));
} else if (!found?.attrs.fontSize && fontSize) {
} else if (!foundTextStyle?.attrs.fontSize && fontSize) {
tr.addMark(pos, pos + node.nodeSize, textStyleType.create({
...found?.attrs,
...foundTextStyle?.attrs,
...fontSize.attrs,
}));
}

// highlight
if (!foundHighlight) {
tr.addMark(pos, pos + node.nodeSize, highlightType.create({
...highlight?.attrs,
}));
}
});

return state.apply(tr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export const handleAnnotationNode = (params) => {
const isMultipleImage = sdtPr?.elements.find((el) => el.name === 'w:fieldMultipleImage')?.attributes['w:val'];
const fontFamily = sdtPr?.elements.find((el) => el.name === 'w:fieldFontFamily')?.attributes['w:val'];
const fontSize = sdtPr?.elements.find((el) => el.name === 'w:fieldFontSize')?.attributes['w:val'];
const textColor = sdtPr?.elements.find((el) => el.name === 'w:fieldTextColor')?.attributes['w:val'];
const textHighlight = sdtPr?.elements.find((el) => el.name === 'w:fieldTextHighlight')?.attributes['w:val'];

const attrs = {
type,
Expand All @@ -38,6 +40,8 @@ export const handleAnnotationNode = (params) => {
multipleImage: isMultipleImage === 'true',
fontFamily: fontFamily !== 'null' ? fontFamily : null,
fontSize: fontSize !== 'null' ? fontSize : null,
textColor: textColor !== 'null' ? textColor : null,
textHighlight: textHighlight !== 'null' ? textHighlight : null,
};

const allAttrs = { ...attrs, ...marksAsAttrs };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,11 @@ const onCreate = ({ editor }) => {
isDebuggingPagination.value = PaginationPluginKey.getState(editor.state)?.isDebugging;

// editor.commands.addFieldAnnotation(0, {
// type: 'html',
// displayLabel: 'Paragraph',
// fieldId: `123`,
// type: 'text',
// displayLabel: 'Some text',
// fieldId: '123',
// fieldType: 'TEXTINPUT',
// fieldColor: '#980043',
// rawHtml: '<p><span style="font-family: Courier New; font-size: 8pt;">Par 1</span></p><p>Par 2</p>',
// });
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,31 @@ export const FieldAnnotation = Node.create({
style: `font-size: ${fontSize}`,
};
},
},

textHighlight: {
default: null,
parseDOM: (element) => element.getAttribute('data-text-highlight'),
renderDOM: (attrs) => {
if (!attrs.textHighlight) return {};
return {
'data-text-highlight': attrs.textHighlight,
// takes precedence over the fieldColor.
style: `background-color: ${attrs.textHighlight} !important`,
};
},
},

textColor: {
default: null,
parseDOM: (element) => element.getAttribute('data-text-color'),
renderDOM: (attrs) => {
if (!attrs.textColor) return {};
return {
'data-text-color': attrs.textColor,
style: `color: ${attrs.textColor}`,
};
},
},
/// Formatting attrs - end.

Expand Down Expand Up @@ -843,6 +867,56 @@ export const FieldAnnotation = Node.create({
}
}

return true;
},

setFieldAnnotationsTextHighlight:
(color, setSelection = false) =>
({ dispatch, tr, state, commands }) => {
let { from, to, node } = state.selection;
let annotations = findFieldAnnotationsBetween(from, to, state.doc);

if (!annotations.length) {
return true;
}

if (dispatch) {
annotations.forEach((annotation) => {
commands.updateFieldAnnotationsAttributes([annotation], {
textHighlight: color,
});
});

if (setSelection && node?.type.name === this.name) {
tr.setSelection(NodeSelection.create(tr.doc, from));
}
}

return true;
},

setFieldAnnotationsTextColor:
(color, setSelection = false) =>
({ dispatch, tr, state, commands }) => {
let { from, to, node } = state.selection;
let annotations = findFieldAnnotationsBetween(from, to, state.doc);

if (!annotations.length) {
return true;
}

if (dispatch) {
annotations.forEach((annotation) => {
commands.updateFieldAnnotationsAttributes([annotation], {
textColor: color,
});
});

if (setSelection && node?.type.name === this.name) {
tr.setSelection(NodeSelection.create(tr.doc, from));
}
}

return true;
},
/// Formatting commands - end.
Expand Down
21 changes: 18 additions & 3 deletions packages/super-editor/src/extensions/table/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { Node, Attribute } from '@core/index.js';
import { callOrGet } from '@core/utilities/callOrGet.js';
import { getExtensionConfigField } from '@core/helpers/getExtensionConfigField.js';
import { /* TableView */ createTableView } from './TableView.js';
import { findParentNodeClosestToPos } from '@helpers/index.js';
import { Fragment } from "prosemirror-model";
import { createTable } from './tableHelpers/createTable.js';
import { createColGroup } from './tableHelpers/createColGroup.js';
import { deleteTableWhenSelected } from './tableHelpers/deleteTableWhenSelected.js';
Expand All @@ -12,8 +10,8 @@ import { createTableBorders } from './tableHelpers/createTableBorders.js';
import { createCellBorders } from '../table-cell/helpers/createCellBorders.js';
import { findParentNode } from '@helpers/findParentNode.js';
import { TextSelection } from 'prosemirror-state';
import { getFieldAttrs } from '@helpers/annotator.js';
import { getNodeType } from '@core/helpers/getNodeType.js';
import { isCellSelection } from './tableHelpers/isCellSelection.js';
import {
addColumnBefore,
addColumnAfter,
Expand Down Expand Up @@ -268,6 +266,23 @@ export const Table = Node.create({
return true;
},

setCellBackground:
(value) => ({ editor, commands, dispatch }) => {
const { selection } = editor.state;

if (!isCellSelection(selection)) {
return false;
}

const color = value?.startsWith('#') ? value.slice(1) : value;

if (dispatch) {
return commands.setCellAttr('background', { color });
}

return true;
},

deleteCellAndTableBorders:
() => ({ chain, state, tr }) => {
if (!isInTable(state)) {
Expand Down
Loading