Skip to content

Commit 0ec3a54

Browse files
committed
fix(paste): detect bold on root element in span-only font-size path
1 parent ab90150 commit 0ec3a54

2 files changed

Lines changed: 22 additions & 11 deletions

File tree

packages/super-editor/src/core/inputRules/google-docs-paste/google-docs-paste.js

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -298,26 +298,27 @@ function convertStyledHeadings(container) {
298298

299299
/**
300300
* Reads font-size (in pt) and bold status from an element's inline style.
301-
* When font-size is on the <p>, bold is accepted from the <p> or all child
302-
* spans. When font-size is only on child spans, all spans must share the same
303-
* size; bold status is reported as whether all spans are bold.
301+
* When font-size is on the root element, bold is accepted from the root or
302+
* all child spans. When font-size is only on child spans, all spans must
303+
* share the same size, and bold is from the root or all child spans.
304304
*
305305
* @param {HTMLElement} el
306306
* @returns {{ fontSize: number|null, isBold: boolean }}
307307
*/
308308
function getHeadingStyleProps(el) {
309309
const elFontSize = parsePtValue(el.style.fontSize);
310+
const elIsBold = boldWeightRegex.test(el.style.fontWeight || '');
310311
const spans = Array.from(el.querySelectorAll('span'));
311-
const allSpansBold = spans.every((span) => boldWeightRegex.test(span.style.fontWeight || ''));
312+
const spanIsBold = (span) => boldWeightRegex.test(span.style.fontWeight || '');
312313
const notHeading = { fontSize: null, isBold: false };
313314

314-
// font-size declared on <p>: bold from <p> itself or if all child spans are bold
315-
const fromElement = () => ({
316-
fontSize: elFontSize,
317-
isBold: boldWeightRegex.test(el.style.fontWeight || '') || (spans.length > 0 && allSpansBold),
318-
});
315+
// font-size declared on root element: bold from itself or if all child spans are bold
316+
const fromElement = () => {
317+
const isBold = elIsBold || (spans.length > 0 && spans.every(spanIsBold));
318+
return { fontSize: elFontSize, isBold };
319+
};
319320

320-
// font-size only on child spans: all must be same size and bold
321+
// font-size only on child spans: all must be same size, then bold from root or all spans
321322
const fromSpans = () => {
322323
// no span children, size is indeterminate
323324
if (spans.length === 0) return notHeading;
@@ -330,7 +331,9 @@ function getHeadingStyleProps(el) {
330331
const [firstSpanSize] = sizes;
331332
if (sizes.some((size) => size !== firstSpanSize)) return notHeading;
332333

333-
return { fontSize: firstSpanSize, isBold: allSpansBold };
334+
// otherwise, first span size, and root element or all spans bold
335+
const isBold = elIsBold || spans.every(spanIsBold);
336+
return { fontSize: firstSpanSize, isBold };
334337
};
335338

336339
return elFontSize !== null ? fromElement() : fromSpans();

packages/super-editor/src/core/inputRules/google-docs-paste/google-docs-paste.test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,14 @@ describe('handleGoogleDocsHtml', () => {
179179
expect(dom.querySelector('p[data-num-id]')).not.toBeNull();
180180
});
181181

182+
it('converts when font-weight is on <p> but font-size is only on the child spans', () => {
183+
const html = `
184+
<p style="font-weight:700"><span style="font-size:20pt">Bold p, size on span</span></p>
185+
`;
186+
const dom = parseHeadings(html);
187+
expect(dom.querySelector('h1')?.textContent?.trim()).toBe('Bold p, size on span');
188+
});
189+
182190
it('converts when font-size is on <p> but font-weight is only on the child <span>', () => {
183191
const html = `
184192
<p style="font-size:20pt"><span style="font-weight:700">Split style heading</span></p>

0 commit comments

Comments
 (0)