Skip to content

Commit 6ffe4a5

Browse files
committed
Fixes for Spark: fonts, and linked styles
1 parent 23f7d2e commit 6ffe4a5

5 files changed

Lines changed: 48 additions & 18 deletions

File tree

packages/super-editor/src/components/toolbar/super-toolbar.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,14 +368,31 @@ export class SuperToolbar extends EventEmitter {
368368
item.deactivate();
369369
}
370370

371+
// Activate toolbar items based on linked styles
372+
const styleIdMark = marks.find((mark) => mark.name === 'styleId');
373+
if (styleIdMark?.attrs.styleId) {
374+
const markToStyleMap = {
375+
fontSize: 'font-size',
376+
fontFamily: 'font-family',
377+
bold: 'bold',
378+
textAlign: 'textAlign',
379+
};
380+
const linkedStyles = this.activeEditor.converter?.linkedStyles.find((style) => style.id === styleIdMark.attrs.styleId);
381+
if (markToStyleMap[item.name.value] in linkedStyles?.definition.styles) {
382+
const value = {
383+
[item.name.value]: linkedStyles?.definition.styles[markToStyleMap[item.name.value]]
384+
};
385+
item.activate(value);
386+
}
387+
}
388+
371389
const spacingAttr = marks.find((mark) => mark.name === 'spacing');
372390
if (item.name.value === 'lineHeight' && (activeMark?.attrs?.lineHeight || spacingAttr)) {
373391
item.selectedValue.value = activeMark?.attrs?.lineHeight || spacingAttr.attrs?.spacing?.line || '';
374392
}
375393

376394
if (item.name.value === 'tableActions') {
377-
if (inTable) item.disabled.value = false;
378-
else item.disabled.value = true;
395+
item.disabled.value = !inTable;
379396
}
380397
});
381398
}

packages/super-editor/src/core/super-converter/helpers.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,16 @@ const rgbToHex = (rgb) => {
142142
.join('');
143143
}
144144

145-
const getLineHeightValueString = (lineHeight, defaultUnit) => {
145+
const getLineHeightValueString = (lineHeight, defaultUnit, lineRule = '', isObject = false) => {
146146
let [value, unit] = parseSizeUnit(lineHeight);
147-
if (Number.isNaN(value)) return {};
147+
if (Number.isNaN(value) || value === 0) return {};
148+
if (lineRule === 'atLeast' && value < 1) return {};
149+
148150
unit = unit ? unit : defaultUnit;
149151

150152
// MS Word has a slightly bigger gap with line spacing equal to Superdoc's
151153
value += unit ? 4 : 0.2;
152-
return `line-height: ${value}${unit}`;
154+
return isObject ? { ['line-height']: `${value}${unit}` } : `line-height: ${value}${unit}`;
153155
}
154156

155157
const deobfuscateFont = (arrayBuffer, guidHex) => {

packages/super-editor/src/core/super-converter/v2/importer/listImporter.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ function handleListNodes({
188188
attrs: {
189189
textAlign: textStyle?.attrs.textAlign || textStyleFromStyles?.attrs.textAlign || null,
190190
rsidRDefault: attributes?.['w:rsidRDefault'] || null,
191+
styleId,
191192
},
192193
content: mergeTextNodes(parNode.content),
193194
};

packages/super-editor/src/extensions/line-height/line-height.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ export const LineHeight = Extension.create({
2323
parseDOM: (el) => el.style.lineHeight,
2424
renderDOM: (attrs) => {
2525
if (!attrs.lineHeight) return {};
26-
return { style: getLineHeightValueString(attrs.lineHeight, this.options.defaults.unit) };
26+
27+
return { style: getLineHeightValueString(attrs.lineHeight, this.options.defaults.unit, attrs.spacing?.lineRule) };
2728
},
2829
},
2930
},

packages/super-editor/src/extensions/linked-styles/linked-styles.js

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const LinkedStyles = Extension.create({
2929
const parentNode = findParentNode((node) => node.type.name === 'paragraph')(tr.selection) || {};
3030
pos = parentNode.pos;
3131
paragraphNode = parentNode.node;
32-
};
32+
}
3333

3434
tr.setNodeMarkup(pos, undefined, {
3535
...paragraphNode.attrs,
@@ -54,15 +54,15 @@ const createLinkedStylesPlugin = (editor) => {
5454
const styles = editor.converter?.linkedStyles || [];
5555
return {
5656
styles,
57-
decorations: generateDecorations(editor.state?.doc, styles),
57+
decorations: generateDecorations(editor.state, styles),
5858
};
5959
},
6060
apply(tr, prev, oldEditorState, newEditorState) {
6161
if (!editor.converter || editor.options.mode !== 'docx') return { ...prev };
6262
let decorations = prev.decorations || DecorationSet.empty;
6363
if (tr.docChanged) {
6464
const styles = LinkedStylesPluginKey.getState(editor.state).styles;
65-
decorations = generateDecorations(newEditorState.doc, styles);
65+
decorations = generateDecorations(newEditorState, styles);
6666
}
6767

6868
return { ...prev, decorations };
@@ -79,13 +79,15 @@ const createLinkedStylesPlugin = (editor) => {
7979
/**
8080
* Generate style decorations for linked styles
8181
*
82-
* @param {Object} doc The current document object
82+
* @param {Object} state Editor state
8383
* @param {Array[Object]} styles The linked styles
8484
* @returns {DecorationSet} The decorations
8585
*/
86-
const generateDecorations = (doc, styles) => {
86+
const generateDecorations = (state, styles) => {
8787
const decorations = [];
8888
let lastStyleId = null;
89+
const doc = state?.doc;
90+
8991
doc.descendants((node, pos) => {
9092
const { name } = node.type;
9193

@@ -97,7 +99,10 @@ const generateDecorations = (doc, styles) => {
9799
const linkedStyle = getLinkedStyle(lastStyleId, styles);
98100
if (!linkedStyle) return;
99101

100-
const styleString = generateLinkedStyleString(linkedStyle, node);
102+
const $pos = state.doc.resolve(pos);
103+
const parent = $pos.parent;
104+
105+
const styleString = generateLinkedStyleString(linkedStyle, node, parent);
101106
if (!styleString) return;
102107

103108
const decoration = Decoration.inline(pos, pos + node.nodeSize, { style: styleString });
@@ -112,9 +117,10 @@ const generateDecorations = (doc, styles) => {
112117
*
113118
* @param {Object} linkedStyle The linked style object
114119
* @param {Object} node The current node
120+
* @param {Object} parent The parent of current
115121
* @returns {String} The style string
116122
*/
117-
export const generateLinkedStyleString = (linkedStyle, node, includeSpacing = true) => {
123+
export const generateLinkedStyleString = (linkedStyle, node, parent, includeSpacing = true) => {
118124
if (!linkedStyle?.definition?.styles) return '';
119125
const markValue = {};
120126

@@ -138,16 +144,19 @@ export const generateLinkedStyleString = (linkedStyle, node, includeSpacing = tr
138144

139145
// Check if this node has the expected mark. If yes, we are not overriding it
140146
const mark = flattenedMarks.find((n) => n.key === key);
147+
const hasParentIndent = Object.keys(parent?.attrs.indent || {});
148+
const hasParentSpacing = Object.keys(parent?.attrs.spacing || {});
141149

142150
// If no mark already in the node, we override the style
143151
if (!mark) {
144-
if (key === 'spacing' && includeSpacing) {
152+
if (key === 'spacing' && includeSpacing && !hasParentSpacing) {
145153
const space = getSpacingStyle(value);
146154
Object.entries(space).forEach(([k, v]) => {
147155
markValue[k] = v;
148156
});
149-
} else if (key === 'indent' && includeSpacing) {
157+
} else if (key === 'indent' && includeSpacing && !hasParentIndent) {
150158
const { leftIndent, rightIndent, firstLine } = value;
159+
151160
if (leftIndent) markValue['margin-left'] = leftIndent + 'px';
152161
if (rightIndent) markValue['margin-right'] = rightIndent + 'px';
153162
if (firstLine) markValue['text-indent'] = firstLine + 'px';
@@ -158,7 +167,7 @@ export const generateLinkedStyleString = (linkedStyle, node, includeSpacing = tr
158167
}
159168
}
160169
});
161-
170+
162171
return Object.entries(markValue).map(([key, value]) => `${key}: ${value}`).join(';');
163172
};
164173

@@ -174,11 +183,11 @@ const getLinkedStyle = (styleId, styles = []) => {
174183
};
175184

176185
export const getSpacingStyle = (spacing) => {
177-
const { lineSpaceBefore, lineSpaceAfter, line } = spacing;
186+
const { lineSpaceBefore, lineSpaceAfter, line, lineRule } = spacing;
178187
return {
179188
'margin-top': lineSpaceBefore + 'px',
180189
'margin-bottom': lineSpaceAfter + 'px',
181-
...getLineHeightValueString(line, '')
190+
...getLineHeightValueString(line, '', lineRule, true)
182191
};
183192
};
184193

0 commit comments

Comments
 (0)