Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/microsoft/roosterjs into …
Browse files Browse the repository at this point in the history
…u/bvalverde/fixWordDesktopLists
  • Loading branch information
BryanValverdeU committed Jan 5, 2024
2 parents b970949 + ccdb5e6 commit 0ff636e
Show file tree
Hide file tree
Showing 31 changed files with 602 additions and 132 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import { alignCenterButton } from './alignCenterButton';
import { alignJustifyButton } from './alignJustifyButton';
import { alignLeftButton } from './alignLeftButton';
import { alignRightButton } from './alignRightButton';
import { backgroundColorButton } from './backgroundColorButton';
Expand Down Expand Up @@ -83,6 +84,7 @@ const buttons = [
alignLeftButton,
alignCenterButton,
alignRightButton,
alignJustifyButton,
insertLinkButton,
removeLinkButton,
insertTableButton,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { isContentModelEditor } from 'roosterjs-content-model-editor';
import { RibbonButton } from 'roosterjs-react';
import { setAlignment } from 'roosterjs-content-model-api';

/**
* @internal
* "Align justify" button on the format ribbon
*/
export const alignJustifyButton: RibbonButton<'buttonNameAlignJustify'> = {
key: 'buttonNameAlignJustify',
unlocalizedText: 'Align justify',
iconName: 'AlignJustify',
onClick: editor => {
if (isContentModelEditor(editor)) {
setAlignment(editor, 'justify');
}
return true;
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import type {
} from 'roosterjs-content-model-types';

const ResultMap: Record<
'left' | 'center' | 'right',
Record<'ltr' | 'rtl', 'start' | 'center' | 'end'>
'left' | 'center' | 'right' | 'justify',
Record<'ltr' | 'rtl', 'start' | 'center' | 'end' | 'justify'>
> = {
left: {
ltr: 'start',
Expand All @@ -22,6 +22,10 @@ const ResultMap: Record<
ltr: 'end',
rtl: 'start',
},
justify: {
ltr: 'justify',
rtl: 'justify',
},
};

const TableAlignMap: Record<
Expand All @@ -47,7 +51,7 @@ const TableAlignMap: Record<
*/
export function setModelAlignment(
model: ContentModelDocument,
alignment: 'left' | 'center' | 'right'
alignment: 'left' | 'center' | 'right' | 'justify'
) {
const paragraphOrListItemOrTable = getOperationalBlocks<ContentModelListItem>(
model,
Expand All @@ -56,15 +60,21 @@ export function setModelAlignment(
);

paragraphOrListItemOrTable.forEach(({ block }) => {
const newAligment = ResultMap[alignment][block.format.direction == 'rtl' ? 'rtl' : 'ltr'];
if (block.blockType === 'Table') {
const newAlignment = ResultMap[alignment][block.format.direction == 'rtl' ? 'rtl' : 'ltr'];
if (block.blockType === 'Table' && alignment !== 'justify') {
alignTable(
block,
TableAlignMap[alignment][block.format.direction == 'rtl' ? 'rtl' : 'ltr']
);
} else if (block) {
if (block.blockType === 'BlockGroup' && block.blockGroupType === 'ListItem') {
block.blocks.forEach(b => {
const { format } = b;
format.textAlign = newAlignment;
});
}
const { format } = block;
format.textAlign = newAligment;
format.textAlign = newAlignment;
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { IStandaloneEditor } from 'roosterjs-content-model-types';
*/
export default function setAlignment(
editor: IStandaloneEditor,
alignment: 'left' | 'center' | 'right'
alignment: 'left' | 'center' | 'right' | 'justify'
) {
editor.focus();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -904,4 +904,73 @@ describe('align left', () => {
});
expect(result).toBeTrue();
});

it('align justify paragraph', () => {
const group = createContentModelDocument();
const para = createParagraph();
const text = createText('test');
text.isSelected = true;
para.segments.push(text);

group.blocks.push(para);

const result = setModelAlignment(group, 'justify');
expect(group).toEqual({
blockGroupType: 'Document',
blocks: [
{
blockType: 'Paragraph',
format: {
textAlign: 'justify',
},
segments: [text],
},
],
});
expect(result).toBeTruthy();
});

it('align justify list item', () => {
const group = createContentModelDocument();
const listLevel = createListLevel('OL');
const listItem = createListItem([listLevel]);
const para = createParagraph();
const para2 = createParagraph();
const text = createText('test');
const text2 = createText('test2');
text.isSelected = true;
text2.isSelected = true;
para.segments.push(text);
para2.segments.push(text2);

listItem.blocks.push(para, para2);

group.blocks.push(listItem);

const result = setModelAlignment(group, 'justify');
expect(group).toEqual({
blockGroupType: 'Document',
blocks: [
{
blockGroupType: 'ListItem',
blockType: 'BlockGroup',
levels: [
{
listType: 'OL',
dataset: {},
format: {},
},
],
blocks: [para, para2],
formatHolder: {
segmentType: 'SelectionMarker',
isSelected: true,
format: {},
},
format: { textAlign: 'justify' },
},
],
});
expect(result).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ describe('setAlignment in list', () => {

function runTest(
list: ContentModelListItem,
alignment: 'left' | 'right' | 'center',
alignment: 'left' | 'right' | 'center' | 'justify',
expectedList: ContentModelListItem | null
) {
const model = createContentModelDocument();
Expand Down Expand Up @@ -916,7 +916,9 @@ describe('setAlignment in list', () => {
blocks: [
{
blockType: 'Paragraph',
format: {},
format: {
textAlign: 'start',
},
segments: [
{
segmentType: 'Text',
Expand Down Expand Up @@ -948,7 +950,9 @@ describe('setAlignment in list', () => {
blocks: [
{
blockType: 'Paragraph',
format: {},
format: {
textAlign: 'start',
},
segments: [
{
segmentType: 'Text',
Expand Down Expand Up @@ -1022,7 +1026,9 @@ describe('setAlignment in list', () => {
blocks: [
{
blockType: 'Paragraph',
format: {},
format: {
textAlign: 'center',
},
segments: [
{
segmentType: 'Text',
Expand Down Expand Up @@ -1098,7 +1104,9 @@ describe('setAlignment in list', () => {
blocks: [
{
blockType: 'Paragraph',
format: {},
format: {
textAlign: 'end',
},
segments: [
{
segmentType: 'Text',
Expand All @@ -1124,4 +1132,84 @@ describe('setAlignment in list', () => {
}
);
});

it('List - apply justify', () => {
runTest(
{
blockGroupType: 'ListItem',
blockType: 'BlockGroup',
levels: [
{
listType: 'OL',
dataset: {},
format: {},
},
],
blocks: [
{
blockType: 'Paragraph',
format: {
textAlign: 'end',
},
segments: [
{
segmentType: 'Text',
text: 'test',
format: {},
},
{
segmentType: 'SelectionMarker',
format: {},
isSelected: true,
},
],
},
],
formatHolder: { segmentType: 'SelectionMarker', isSelected: true, format: {} },
format: {
textAlign: 'end',
},
},
'justify',
{
blockGroupType: 'ListItem',
blockType: 'BlockGroup',
levels: [
{
listType: 'OL',
dataset: {},
format: {},
},
],
blocks: [
{
blockType: 'Paragraph',
format: {
textAlign: 'justify',
},
segments: [
{
segmentType: 'Text',
text: 'test',
format: {},
},
{
segmentType: 'SelectionMarker',
format: {},
isSelected: true,
},
],
},
],
formatHolder: {
segmentType: 'SelectionMarker',
isSelected: true,
format: {},
},
format: {
textAlign: 'justify',
},
}
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { FormatParser, SizeFormat } from 'roosterjs-content-model-types';

/**
* @internal Do not paste width for Format Containers since it may be generated by browser according to temp div width
*/
export const containerWidthFormatParser: FormatParser<SizeFormat> = (format, element) => {
// For pasted content, there may be existing width generated by browser from the temp DIV. So we need to remove it.
if (element.tagName == 'DIV') {
delete format.width;
}
};
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import {
AllowedTags,
DisallowedTags,
removeStyle,
sanitizeElement,
} from '../utils/sanitizeElement';
import type { DomToModelOptionForPaste, ElementProcessor } from 'roosterjs-content-model-types';
import { AllowedTags, DisallowedTags, sanitizeElement } from '../utils/sanitizeElement';
import type {
DomToModelOptionForPaste,
ElementProcessor,
ValueSanitizer,
} from 'roosterjs-content-model-types';

const DefaultStyleSanitizers: Readonly<Record<string, ValueSanitizer>> = {
position: false,
};

/**
* @internal
Expand All @@ -14,11 +17,17 @@ export function createPasteEntityProcessor(
): ElementProcessor<HTMLElement> {
const allowedTags = AllowedTags.concat(options.additionalAllowedTags);
const disallowedTags = DisallowedTags.concat(options.additionalDisallowedTags);
const styleSanitizers = Object.assign({}, DefaultStyleSanitizers, options.styleSanitizers);
const attrSanitizers = options.attributeSanitizers;

return (group, element, context) => {
const sanitizedElement = sanitizeElement(element, allowedTags, disallowedTags, {
position: removeStyle,
});
const sanitizedElement = sanitizeElement(
element,
allowedTags,
disallowedTags,
styleSanitizers,
attrSanitizers
);

if (sanitizedElement) {
context.defaultElementProcessors.entity(group, sanitizedElement, context);
Expand Down
Loading

0 comments on commit 0ff636e

Please sign in to comment.