Skip to content

Commit

Permalink
Set segmentFormat text color to black when creating the model of the …
Browse files Browse the repository at this point in the history
…clipboard content and using Keep source formatting paste type (#2773)

* init

* add a link to tests and make sure it is handled correctly
  • Loading branch information
BryanValverdeU authored Aug 29, 2024
1 parent 5b07b94 commit 1af04a3
Show file tree
Hide file tree
Showing 4 changed files with 1,183 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ import type {
ClipboardData,
CloneModelOptions,
ContentModelDocument,
ContentModelSegmentFormat,
IEditor,
MergeModelOption,
PasteType,
ReadonlyContentModelDocument,
ShallowMutableContentModelDocument,
} from 'roosterjs-content-model-types';

const BlackColor = 'rgb(0,0,0)';

const CloneOption: CloneModelOptions = {
includeCachedElement: (node, type) => (type == 'cache' ? undefined : node),
};
Expand Down Expand Up @@ -46,17 +51,14 @@ export function mergePasteContent(
model.blocks = clonedModel.blocks;
}

const selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];
const domToModelContext = createDomToModelContextForSanitizing(
editor.getDocument(),
undefined /*defaultFormat*/,
editor.getEnvironment().domToModelSettings.customized,
domToModelOption
);

domToModelContext.segmentFormat = selectedSegment
? getSegmentTextFormat(selectedSegment)
: {};
domToModelContext.segmentFormat = getSegmentFormatForPaste(model, pasteType);

const pasteModel = domToContentModel(fragment, domToModelContext);
const mergeOption: MergeModelOption = {
Expand Down Expand Up @@ -87,6 +89,27 @@ export function mergePasteContent(
);
}

function getSegmentFormatForPaste(
model: ShallowMutableContentModelDocument,
pasteType: PasteType
): ContentModelSegmentFormat {
const selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];

if (selectedSegment) {
const result = getSegmentTextFormat(selectedSegment);
if (pasteType == 'normal') {
// When using normal paste (Keep source formatting) set the default text color to black when creating the
// Model from the clipboard content, so the elements that do not contain any text color in their style
// Are set to black. Otherwise, These segments would get the selected segments format or the default text set in the content.
result.textColor = BlackColor;
}

return result;
}

return {};
}

function shouldMergeTable(pasteModel: ContentModelDocument): boolean | undefined {
// If model contains a table and a paragraph element after the table with a single BR segment, remove the Paragraph after the table
if (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
export const template: Readonly<string> = `
<html
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns:m="http://schemas.microsoft.com/office/2004/12/omml"
xmlns="http://www.w3.org/TR/REC-html40"
>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 15" />
<meta name="Originator" content="Microsoft Word 15" />
<!--[if gte mso 9
]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG />
</o:OfficeDocumentSettings> </xml
><![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;
mso-font-charset:0;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:-536869121 1107305727 33554432 0 415 0;}
@font-face
{font-family:"Yu Gothic";
panose-1:2 11 4 0 0 0 0 0 0 0;
mso-font-alt:游ゴシック;
mso-font-charset:128;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-536870145 717749759 22 0 131231 0;}
@font-face
{font-family:Aptos;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:536871559 3 0 0 415 0;}
@font-face
{font-family:"\@Yu Gothic";
panose-1:2 11 4 0 0 0 0 0 0 0;
mso-font-charset:128;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-536870145 717749759 22 0 131231 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0in;
margin-right:0in;
margin-bottom:8.0pt;
margin-left:0in;
line-height:115%;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Aptos",sans-serif;
mso-ascii-font-family:Aptos;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:"Yu Gothic";
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Aptos;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;
mso-font-kerning:1.0pt;
mso-ligatures:standardcontextual;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
font-family:"Aptos",sans-serif;
mso-ascii-font-family:Aptos;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:"Yu Gothic";
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Aptos;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:8.0pt;
line-height:115%;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-paper-source:0;}
div.WordSection1
{page:WordSection1;}
-->
</style>
<!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable {
mso-style-name: 'Table Normal';
mso-tstyle-rowband-size: 0;
mso-tstyle-colband-size: 0;
mso-style-noshow: yes;
mso-style-priority: 99;
mso-style-parent: '';
mso-padding-alt: 0in 5.4pt 0in 5.4pt;
mso-para-margin-top: 0in;
mso-para-margin-right: 0in;
mso-para-margin-bottom: 8pt;
mso-para-margin-left: 0in;
line-height: 115%;
mso-pagination: widow-orphan;
font-size: 12pt;
font-family: 'Aptos', sans-serif;
mso-ascii-font-family: Aptos;
mso-ascii-theme-font: minor-latin;
mso-hansi-font-family: Aptos;
mso-hansi-theme-font: minor-latin;
mso-font-kerning: 1pt;
mso-ligatures: standardcontextual;
}
</style>
<![endif]-->
</head>
<body lang="EN-US" style="tab-interval: 0.5in; word-wrap: break-word;">
<!--StartFragment-->
<p class="MsoNormal">
<b
><span style="font-size: 28pt; line-height: 115%; color: #c00000;"
>Red bold<o:p></o:p></span
></b>
</p>
<p class="MsoNormal">
<i
><span style="font-size: 28pt; line-height: 115%; color: #c00000;"
>Red italic<o:p></o:p></span
></i>
</p>
<p class="MsoNormal">
<u
><span style="font-size: 28pt; line-height: 115%; color: #c00000;"
>Red underline<o:p></o:p></span
></u>
</p>
<p class="MsoNormal">
<span style="font-size: 28pt; line-height: 115%;">Unformatted line<o:p></o:p></span>
</p>
<p class="MsoNormal">
<u
><a href="https://github.com/microsoft/roosterjs" style="font-size: 28pt; line-height: 115%;"
>Text underlink<o:p></o:p></a
></u>
</p>
<!--EndFragment-->
</body>
</html>
`;
Loading

0 comments on commit 1af04a3

Please sign in to comment.