Skip to content

Commit

Permalink
Merge branch 'master' into u/bvalverde/supportCellPaddingScpaing
Browse files Browse the repository at this point in the history
  • Loading branch information
BryanValverdeU authored Oct 2, 2024
2 parents 8cc09f4 + eb4127c commit 79c9000
Show file tree
Hide file tree
Showing 15 changed files with 429 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const initialState: OptionState = {
handleTabKey: true,
},
customReplacements: emojiReplacements,
experimentalFeatures: new Set<ExperimentalFeature>(['PersistCache']),
experimentalFeatures: new Set<ExperimentalFeature>(['PersistCache', 'HandleEnterKey']),
};

export class EditorOptionsPlugin extends SidePanePluginImpl<OptionsPane, OptionPaneProps> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ export interface DefaultFormatProps {

export class ExperimentalFeatures extends React.Component<DefaultFormatProps, {}> {
render() {
return this.renderFeature('PersistCache');
return (
<>
{this.renderFeature('PersistCache')}
{this.renderFeature('HandleEnterKey')}
{this.renderFeature('LegacyImageSelection')}
</>
);
}

private renderFeature(featureName: ExperimentalFeature): JSX.Element {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import type {
ReadonlyTableSelectionContext,
} from 'roosterjs-content-model-types';

const TEMP_DIV_ID = 'roosterJS_copyCutTempDiv';

/**
* Copy and paste plugin for handling onCopy and onPaste event
*/
Expand Down Expand Up @@ -235,6 +237,7 @@ class CopyPastePlugin implements PluginWithState<CopyPastePluginState> {
div.childNodes.forEach(node => div.removeChild(node));

div.style.display = '';
div.id = TEMP_DIV_ID;
div.focus();

return div;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ class DOMHelperImpl implements DOMHelper {
const paddingRight = parseValueWithUnit(style?.paddingRight);
return this.contentDiv.clientWidth - (paddingLeft + paddingRight);
}

/**
* Get a deep cloned root element
*/
getClonedRoot(): HTMLElement {
return this.contentDiv.cloneNode(true /*deep*/) as HTMLElement;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,4 +350,20 @@ describe('DOMHelperImpl', () => {
expect(domHelper.getClientWidth()).toBe(1000);
});
});

describe('getClonedRoot', () => {
it('getClonedRoot', () => {
const mockedClone = 'CLONE' as any;
const cloneSpy = jasmine.createSpy('cloneSpy').and.returnValue(mockedClone);
const mockedDiv: HTMLElement = {
cloneNode: cloneSpy,
} as any;
const domHelper = createDOMHelper(mockedDiv);

const result = domHelper.getClonedRoot();

expect(result).toBe(mockedClone);
expect(cloneSpy).toHaveBeenCalledWith(true);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import { addSegment } from '../../modelApi/common/addSegment';
import { createBr } from '../../modelApi/creators/createBr';
import { getRegularSelectionOffsets } from '../utils/getRegularSelectionOffsets';
import type { ElementProcessor } from 'roosterjs-content-model-types';

/**
* @internal
*/
export const brProcessor: ElementProcessor<HTMLBRElement> = (group, element, context) => {
const br = createBr(context.segmentFormat);
const [start, end] = getRegularSelectionOffsets(context, element);

if (start >= 0) {
context.isInSelection = true;
}

if (context.isInSelection) {
br.isSelected = true;
}

const paragraph = addSegment(group, br, context.blockFormat);

if (end >= 0) {
context.isInSelection = false;
}

context.domIndexer?.onSegment(element, paragraph, [br]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,22 @@ export function mergeModel(
const insertPosition =
options?.insertPosition ?? deleteSelection(target, [], context).insertPoint;

if (options?.addParagraphAfterMergedContent) {
const { addParagraphAfterMergedContent, mergeFormat, mergeTable } = options || {};

if (addParagraphAfterMergedContent && !mergeTable) {
const { paragraph, marker } = insertPosition || {};
const newPara = createParagraph(false /* isImplicit */, paragraph?.format, marker?.format);
addBlock(source, newPara);
}

if (insertPosition) {
if (options?.mergeFormat && options.mergeFormat != 'none') {
if (mergeFormat && mergeFormat != 'none') {
const newFormat: ContentModelSegmentFormat = {
...(target.format || {}),
...insertPosition.marker.format,
};

applyDefaultFormat(source, newFormat, options?.mergeFormat);
applyDefaultFormat(source, newFormat, mergeFormat);
}

for (let i = 0; i < source.blocks.length; i++) {
Expand All @@ -84,8 +86,8 @@ export function mergeModel(
break;

case 'Table':
if (source.blocks.length == 1 && options?.mergeTable) {
mergeTable(insertPosition, block, source);
if (source.blocks.length == 1 && mergeTable) {
mergeTables(insertPosition, block, source);
} else {
insertBlock(insertPosition, block);
}
Expand Down Expand Up @@ -176,7 +178,7 @@ function mergeParagraph(
}
}

function mergeTable(
function mergeTables(
markerPosition: InsertPoint,
newTable: ContentModelTable,
source: ContentModelDocument
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,74 @@ describe('brProcessor', () => {
});
expect(onSegmentSpy).toHaveBeenCalledWith(br, paragraphModel, [brModel]);
});

it('Selection starts in BR', () => {
const doc = createContentModelDocument();
const div = document.createElement('div');
const br = document.createElement('br');
const range = document.createRange();

div.appendChild(br);
range.setStart(br, 0);
range.setEnd(div, 1);
context.selection = {
type: 'range',
range: range,
isReverted: false,
};

brProcessor(doc, br, context);

const brModel: ContentModelBr = {
segmentType: 'Br',
format: {},
isSelected: true,
};
const paragraphModel: ContentModelParagraph = {
blockType: 'Paragraph',
isImplicit: true,
segments: [brModel],
format: {},
};

expect(doc).toEqual({
blockGroupType: 'Document',
blocks: [paragraphModel],
});
expect(context.isInSelection).toBeTrue();
});

it('Selection ends in BR', () => {
const doc = createContentModelDocument();
const br = document.createElement('br');
const range = document.createRange();

range.setEnd(br, 0);
context.selection = {
type: 'range',
range: range,
isReverted: false,
};
context.isInSelection = true;

brProcessor(doc, br, context);

const brModel: ContentModelBr = {
segmentType: 'Br',
format: {},
isSelected: true,
};
const paragraphModel: ContentModelParagraph = {
blockType: 'Paragraph',
isImplicit: true,
segments: [brModel],
format: {},
};

expect(doc).toEqual({
blockGroupType: 'Document',
blocks: [paragraphModel],
});
expect(context.isInSelection).toBeFalse();
});
});
Loading

0 comments on commit 79c9000

Please sign in to comment.