Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump RoosterJS version to 8.56 and Content Model to 0.16 #2093

Merged
merged 99 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
d6a390c
Content Model: Improve cache behavior (#1999)
JiuqingSong Aug 4, 2023
795c00d
Skip Trigger plugin event on plain text paste (#2011)
BryanValverdeU Aug 8, 2023
4680506
Fix 218869: Do not allow dragging on readonly content (#2010)
JiuqingSong Aug 8, 2023
aa49e67
Content Model: Fix 194024 and 220289 (#2012)
JiuqingSong Aug 8, 2023
e8d2536
Content Model: Fix 221290 Support float for image (#2013)
JiuqingSong Aug 8, 2023
6eecbc7
Content Model: improve formatWithContentModel 1 (#2001)
JiuqingSong Aug 8, 2023
991fed1
Content Model: improve formatWithContentModel 2 (#2002)
JiuqingSong Aug 9, 2023
0ea0095
WIP
juliaroldi Aug 9, 2023
be1ffcb
fix handles
juliaroldi Aug 9, 2023
84e8f2e
Merge branch 'master' into u/juliaroldi/image-bugs-part-2
juliaroldi Aug 9, 2023
72f0c87
MergeModel, do not inherit the styles of table when splitting the par…
BryanValverdeU Aug 9, 2023
ce9f802
fixes
juliaroldi Aug 9, 2023
410bfbd
Merge branch 'master' into u/juliaroldi/image-bugs-part-2
juliaroldi Aug 10, 2023
a1a7b81
Demo site: Fix insert link button in Content Model ribbon (#2018)
JiuqingSong Aug 10, 2023
349d30a
Merge branch 'master' into u/juliaroldi/image-bugs-part-2
juliaroldi Aug 10, 2023
69005d6
Merge pull request #2017 from microsoft/u/juliaroldi/image-bugs-part-2
juliaroldi Aug 10, 2023
a8a9592
Content Model: insertEntity API (#1800)
JiuqingSong Aug 11, 2023
dec835d
crop
juliaroldi Aug 11, 2023
f44cc25
fix xase
juliaroldi Aug 11, 2023
7731317
Merge pull request #2019 from microsoft/u/juliaroldi/cropper
juliaroldi Aug 11, 2023
4d37ad2
check cell exist
juliaroldi Aug 11, 2023
7e722e5
Fix #1752, rename header to heading (#2020)
JiuqingSong Aug 11, 2023
06736fa
fix cell empty cells
juliaroldi Aug 14, 2023
0c6f947
Merge branch 'master' into u/juliaroldi/empty-cells
juliaroldi Aug 14, 2023
a417d9e
Merge pull request #2027 from microsoft/u/juliaroldi/empty-cells
juliaroldi Aug 14, 2023
6d610cd
fix flipped image
juliaroldi Aug 14, 2023
a4f0941
Merge branch 'master' into u/juliaroldi/image-flipped
juliaroldi Aug 14, 2023
e1a5c28
Merge pull request #2028 from microsoft/u/juliaroldi/image-flipped
juliaroldi Aug 14, 2023
a2b9804
Update logic to decide if we need to merge a table on paste. (#2022)
BryanValverdeU Aug 15, 2023
ce15217
Content Model: Rename a test file (#2029)
JiuqingSong Aug 15, 2023
560db30
Fix Triple clicking a single cell selecting more than one (#2024)
Andres-CT98 Aug 15, 2023
8c7fa2b
Remove `display: flex` style on paste (#2031)
BryanValverdeU Aug 16, 2023
f03f701
Replace first cell content if input while on cell selection (#2030)
Andres-CT98 Aug 17, 2023
2875a23
Content Model: Fix 222135 (#2035)
JiuqingSong Aug 17, 2023
14386b6
Content Model: Fix 219312 (#2036)
JiuqingSong Aug 17, 2023
8a200e7
Fix regression when creating the BeforePasteEvent (#2039)
BryanValverdeU Aug 18, 2023
dbf5617
Content Model: Fix 220050 (#2037)
JiuqingSong Aug 18, 2023
665ab68
Simplify the domToModel call in `paste.ts` (#2040)
BryanValverdeU Aug 18, 2023
7c6a320
Content Model: Support vertical-align for image (#2041)
JiuqingSong Aug 18, 2023
0439b5a
Remove deprecated colors from borders, text and background. (#2045)
BryanValverdeU Aug 29, 2023
2aec57c
reselection
juliaroldi Sep 4, 2023
d38fa72
add space
juliaroldi Sep 4, 2023
4f5bd68
Content Model: Improve insertEntity (#2047)
JiuqingSong Sep 5, 2023
04dd124
Merge branch 'master' into u/juliaroldi/getImage-fix
juliaroldi Sep 5, 2023
764481a
Merge pull request #2049 from microsoft/u/juliaroldi/getImage-fix
juliaroldi Sep 5, 2023
6c1c78f
Content Model: Fix selection of entity (#2051)
JiuqingSong Sep 8, 2023
d29815f
Content Model: Always return size in pt when getFormatState (#2052)
JiuqingSong Sep 8, 2023
2fc7830
Content Model: trigger ShadowEdit events (#2053)
JiuqingSong Sep 8, 2023
fb0febc
Content Model: Add solid paragraph in new table cell (#2055)
JiuqingSong Sep 8, 2023
f3f6831
Content Model: Do color transform for entity when copy/paste (#2056)
JiuqingSong Sep 8, 2023
bf80705
Content Model: Paste plain text applies current format (#2057)
JiuqingSong Sep 8, 2023
b77c854
Content Model: Fix a regression of shadow edit (#2058)
JiuqingSong Sep 8, 2023
d047ca3
deprecate auto format list
juliaroldi Sep 11, 2023
e47e639
remove code
juliaroldi Sep 11, 2023
b054984
fix build
juliaroldi Sep 11, 2023
34b0eb6
remove tests
juliaroldi Sep 11, 2023
8f99244
Merge pull request #2062 from microsoft/u/juliaroldi/deprecate-autofo…
juliaroldi Sep 11, 2023
c98ea0b
fix rotator
juliaroldi Sep 15, 2023
b27157c
Content Model: Fix line space when reduce font size (#2059)
JiuqingSong Sep 15, 2023
1589a3a
Content Model Customization refactor 0 (#2068)
JiuqingSong Sep 15, 2023
0a59567
Merge branch 'master' into u/juliaroldi/adjust-rotate-handle
juliaroldi Sep 18, 2023
afcaf70
Merge pull request #2071 from microsoft/u/juliaroldi/adjust-rotate-ha…
juliaroldi Sep 18, 2023
ff47d9f
Content Model Customization refactor 1 (#2054)
JiuqingSong Sep 18, 2023
e8e0462
Remove Segment format from the pasted content when the format merge o…
BryanValverdeU Sep 18, 2023
e214063
fix image link deletion
juliaroldi Sep 18, 2023
ad07b90
refactor
juliaroldi Sep 18, 2023
98a4487
remove empty links
juliaroldi Sep 18, 2023
0ebe6eb
Merge branch 'master' of https://github.com/microsoft/roosterjs into …
juliaroldi Sep 18, 2023
aae5e4e
space
juliaroldi Sep 18, 2023
a76905c
Content Model Customization refactor 2 (#2064)
JiuqingSong Sep 19, 2023
67e21e3
Merge branch 'master' of https://github.com/microsoft/roosterjs into …
juliaroldi Sep 19, 2023
a364e4d
refactor
juliaroldi Sep 19, 2023
7bf0557
Merge pull request #2077 from microsoft/u/juliaroldi/delete-link-on-i…
juliaroldi Sep 19, 2023
f37889a
fix table cell alignment
juliaroldi Sep 19, 2023
51eb85c
Content Model Cache improvement 1: Create ContentModelCachePlugin (#2…
JiuqingSong Sep 19, 2023
73bad0b
Merge branch 'master' into u/juliaroldi/table-alignment-cell-block
juliaroldi Sep 19, 2023
bb96d2e
Merge pull request #2082 from microsoft/u/juliaroldi/table-alignment-…
juliaroldi Sep 19, 2023
5cef7ba
Content Model: pass out segment nodes (#2079)
JiuqingSong Sep 19, 2023
187e032
Do not restore cached selection when call select (#2075)
JiuqingSong Sep 20, 2023
b4ca8e2
Improve "checkDependency" (#2085)
JiuqingSong Sep 21, 2023
bee1d42
Content Model: Improve adjustWordSelection (#2087)
JiuqingSong Sep 21, 2023
f8e3096
Fix #2084 (#2089)
JiuqingSong Sep 21, 2023
cd26ced
fix text color in tables
juliaroldi Sep 21, 2023
47dd150
fix test
juliaroldi Sep 21, 2023
750dab2
fix tests
juliaroldi Sep 21, 2023
b7bb78b
remove code
juliaroldi Sep 21, 2023
3585d22
remove code
juliaroldi Sep 21, 2023
2987062
Merge branch 'master' into romasha/versionbump921
romanisa Sep 21, 2023
e808fbf
Do not consider Bold, Italic and Underline from ContentModelDocument …
BryanValverdeU Sep 21, 2023
f152042
Update RoosterJS version to 8.56 and content model to 0.16
romanisa Sep 21, 2023
08560dc
Merge branch 'master' into romasha/versionbump921
romanisa Sep 21, 2023
4fc1f3a
Fix files that were merged wrongly
romanisa Sep 21, 2023
46ffb8a
Also bumping UI package version
romanisa Sep 21, 2023
43da112
select new row/column (#2094)
Andres-CT98 Sep 21, 2023
31fa011
Content Model: Add model into ContentChangedEvent (#2076)
JiuqingSong Sep 22, 2023
355b651
Merge branch 'master' into u/juliaroldi/background-table
juliaroldi Sep 22, 2023
3d640fa
rename variable
juliaroldi Sep 22, 2023
0e6ac85
Merge pull request #2091 from microsoft/u/juliaroldi/background-table
juliaroldi Sep 22, 2023
0c37988
Merge branch 'master' into romasha/versionbump921
romanisa Sep 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions demo/scripts/controls/ContentModelEditorMainPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import * as React from 'react';
import * as ReactDOM from 'react-dom';
import ApiPlaygroundPlugin from './sidePane/contentModelApiPlayground/ApiPlaygroundPlugin';
import ContentModelEditorOptionsPlugin from './sidePane/editorOptions/ContentModelEditorOptionsPlugin';
import ContentModelEventViewPlugin from './sidePane/eventViewer/ContentModelEventViewPlugin';
import ContentModelFormatPainterPlugin from './contentModel/plugins/ContentModelFormatPainterPlugin';
import ContentModelFormatStatePlugin from './sidePane/formatState/ContentModelFormatStatePlugin';
import ContentModelPanePlugin from './sidePane/contentModel/ContentModelPanePlugin';
import ContentModelRibbon from './ribbonButtons/contentModel/ContentModelRibbon';
import EventViewPlugin from './sidePane/eventViewer/EventViewPlugin';
import getToggleablePlugins from './getToggleablePlugins';
import MainPaneBase from './MainPaneBase';
import SampleEntityPlugin from './sampleEntity/SampleEntityPlugin';
Expand Down Expand Up @@ -84,7 +84,7 @@ const DarkTheme: PartialTheme = {
class ContentModelEditorMainPane extends MainPaneBase {
private formatStatePlugin: ContentModelFormatStatePlugin;
private editorOptionPlugin: ContentModelEditorOptionsPlugin;
private eventViewPlugin: EventViewPlugin;
private eventViewPlugin: ContentModelEventViewPlugin;
private apiPlaygroundPlugin: ApiPlaygroundPlugin;
private ContentModelPanePlugin: ContentModelPanePlugin;
private ribbonPlugin: RibbonPlugin;
Expand All @@ -100,7 +100,7 @@ class ContentModelEditorMainPane extends MainPaneBase {

this.formatStatePlugin = new ContentModelFormatStatePlugin();
this.editorOptionPlugin = new ContentModelEditorOptionsPlugin();
this.eventViewPlugin = new EventViewPlugin();
this.eventViewPlugin = new ContentModelEventViewPlugin();
this.apiPlaygroundPlugin = new ApiPlaygroundPlugin();
this.snapshotPlugin = new SnapshotPlugin();
this.ContentModelPanePlugin = new ContentModelPanePlugin();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ const initialState: BuildInPluginState = {
watermarkText: 'Type content here ...',
forcePreserveRatio: false,
experimentalFeatures: [
ExperimentalFeatures.AutoFormatList,
ExperimentalFeatures.InlineEntityReadOnlyDelimiters,
ExperimentalFeatures.ContentModelPaste,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ export interface ExperimentalFeaturesProps {

const FeatureNames: Partial<Record<ExperimentalFeatures, string>> = {
[ExperimentalFeatures.TabKeyTextFeatures]: 'Additional functionality to Tab Key',
[ExperimentalFeatures.AutoFormatList]:
'Trigger formatting by a especial characters. Ex: (A), 1. i).',
[ExperimentalFeatures.ReuseAllAncestorListElements]:
"Reuse ancestor list elements even if they don't match the types from the list item.",
[ExperimentalFeatures.DeleteTableWithBackspace]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ const initialState: BuildInPluginState = {
linkTitle: 'Ctrl+Click to follow the link:' + UrlPlaceholder,
watermarkText: 'Type content here ...',
forcePreserveRatio: false,
experimentalFeatures: [
ExperimentalFeatures.AutoFormatList,
ExperimentalFeatures.InlineEntityReadOnlyDelimiters,
],
experimentalFeatures: [ExperimentalFeatures.InlineEntityReadOnlyDelimiters],
isRtl: false,
tableFeaturesContainerSelector: '#' + 'EditorContainer',
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ export interface ExperimentalFeaturesProps {

const FeatureNames: Partial<Record<ExperimentalFeatures, string>> = {
[ExperimentalFeatures.TabKeyTextFeatures]: 'Additional functionality to Tab Key',
[ExperimentalFeatures.AutoFormatList]:
'Trigger formatting by a especial characters. Ex: (A), 1. i).',
[ExperimentalFeatures.ReuseAllAncestorListElements]:
"Reuse ancestor list elements even if they don't match the types from the list item.",
[ExperimentalFeatures.DeleteTableWithBackspace]:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,324 @@
import * as React from 'react';
import { ContentModelContentChangedEvent } from 'roosterjs-content-model-editor';
import { EntityOperation, PluginEvent, PluginEventType } from 'roosterjs-editor-types';
import { SidePaneElementProps } from '../SidePaneElement';
import {
getObjectKeys,
getTagOfNode,
HtmlSanitizer,
readFile,
safeInstanceOf,
} from 'roosterjs-editor-dom';

const styles = require('./EventViewPane.scss');

export interface EventEntry {
index: number;
time: Date;
event: PluginEvent;
}

export interface EventViewPaneState {
displayCount: number;
currentIndex: number;
}

const EventTypeMap: { [key in PluginEventType]: string } = {
[PluginEventType.BeforeDispose]: 'BeforeDispose',
[PluginEventType.BeforePaste]: 'BeforePaste',
[PluginEventType.CompositionEnd]: 'CompositionEnd',
[PluginEventType.ContentChanged]: 'ContentChanged',
[PluginEventType.EditorReady]: 'EditorReady',
[PluginEventType.EntityOperation]: 'EntityOperation',
[PluginEventType.ExtractContentWithDom]: 'ExtractContentWithDom',
[PluginEventType.KeyDown]: 'KeyDown',
[PluginEventType.KeyPress]: 'KeyPress',
[PluginEventType.KeyUp]: 'KeyUp',
[PluginEventType.MouseDown]: 'MouseDown',
[PluginEventType.MouseUp]: 'MouseUp',
[PluginEventType.Input]: 'Input',
[PluginEventType.PendingFormatStateChanged]: 'PendingFormatStateChanged',
[PluginEventType.Scroll]: 'Scroll',
[PluginEventType.BeforeCutCopy]: 'BeforeCutCopy',
[PluginEventType.ContextMenu]: 'ContextMenu',
[PluginEventType.EnteredShadowEdit]: 'EnteredShadowEdit',
[PluginEventType.LeavingShadowEdit]: 'LeavingShadowEdit',
[PluginEventType.EditImage]: 'EditImage',
[PluginEventType.BeforeSetContent]: 'BeforeSetContent',
[PluginEventType.ZoomChanged]: 'ZoomChanged',
[PluginEventType.SelectionChanged]: 'SelectionChanged',
[PluginEventType.BeforeKeyboardEditing]: 'BeforeKeyboardEditing',
};

const EntityOperationMap: { [key in EntityOperation]: string } = {
[EntityOperation.AddShadowRoot]: 'AddShadowRoot',
[EntityOperation.RemoveShadowRoot]: 'RemoveShadowRoot',
[EntityOperation.Click]: 'Click',
[EntityOperation.ContextMenu]: 'ContextMenu',
[EntityOperation.Escape]: 'Escape',
[EntityOperation.NewEntity]: 'NewEntity',
[EntityOperation.Overwrite]: 'Overwrite',
[EntityOperation.PartialOverwrite]: 'PartialOverwrite',
[EntityOperation.RemoveFromEnd]: 'RemoveFromEnd',
[EntityOperation.RemoveFromStart]: 'RemoveFromStart',
[EntityOperation.ReplaceTemporaryContent]: 'ReplaceTemporaryContent',
[EntityOperation.UpdateEntityState]: 'UpdateEntityState',
};

export default class ContentModelEventViewPane extends React.Component<
SidePaneElementProps,
EventViewPaneState
> {
private events: EventEntry[] = [];
private displayCount = React.createRef<HTMLSelectElement>();
private lastIndex = 0;

constructor(props: SidePaneElementProps) {
super(props);
this.state = {
displayCount: 20,
currentIndex: -1,
};
}

render() {
let displayCount = Math.min(this.events.length, this.state.displayCount);
let displayedEvents =
displayCount > 0 ? this.events.slice(this.events.length - displayCount) : [];
displayedEvents = displayedEvents.reverse();

return (
<>
<div>
Show item count:
<select
defaultValue={this.state.displayCount.toString()}
ref={this.displayCount}
onChange={this.onDisplayCountChanged}>
<option value={'0'}>Disabled</option>
<option value={'20'}>20</option>
<option value={'50'}>50</option>
<option value={'100'}>100</option>
</select>{' '}
<button onClick={this.clear}>Clear all</button>
</div>
<div>
{displayedEvents.map(event => (
<details key={event.index.toString()}>
<summary>
{`${event.time.getHours()}:${event.time.getMinutes()}:${event.time.getSeconds()}.${event.time.getMilliseconds()} `}
{EventTypeMap[event.event.eventType]}
</summary>
<div className={styles.eventContent}>
{this.renderEvent(event.event)}
</div>
</details>
))}
</div>
</>
);
}

addEvent(event: PluginEvent) {
if (this.state.displayCount > 0) {
if (event.eventType == PluginEventType.BeforePaste) {
const sanitizer = new HtmlSanitizer(event.sanitizingOption);
const fragment = event.fragment.cloneNode(true /*deep*/) as DocumentFragment;

sanitizer.convertGlobalCssToInlineCss(fragment);
sanitizer.sanitize(fragment);
(event.clipboardData as any).html = this.getHtml(fragment);
}

this.events.push({
time: new Date(),
event: event,
index: this.lastIndex++,
});

while (this.events.length > 100) {
this.events.shift();
}
this.setState({
currentIndex: this.lastIndex,
});
}
}

private renderEvent(event: PluginEvent): JSX.Element {
switch (event.eventType) {
case PluginEventType.KeyDown:
case PluginEventType.KeyPress:
case PluginEventType.KeyUp:
return (
<span>
Key=
{event.rawEvent.which}
</span>
);

case PluginEventType.MouseDown:
case PluginEventType.MouseUp:
case PluginEventType.ContextMenu:
return (
<span>
Button=
{event.rawEvent.button}, SrcElement=
{event.rawEvent.target && getTagOfNode(event.rawEvent.target as Node)},
PageX=
{event.rawEvent.pageX}, PageY=
{event.rawEvent.pageY}
</span>
);

case PluginEventType.ContentChanged:
return (
<span>
Source=
{event.source}, Data=
{event.data && event.data.toString && event.data.toString()}
{!!(event as ContentModelContentChangedEvent).contentModel && (
<details>
<summary>Content Model</summary>
<pre className={styles.eventContent}>
{JSON.stringify(
(event as ContentModelContentChangedEvent).contentModel,
(key, value) =>
safeInstanceOf(value, 'Node')
? Object.prototype.toString.apply(value)
: key == 'src'
? value.length > 100
? value.substring(0, 97) + '...'
: value
: value,
2
)}
</pre>
</details>
)}
</span>
);

case PluginEventType.BeforePaste:
return (
<span>
Types=
{event.clipboardData.types.join()}
{this.renderPasteContent('Plain text', event.clipboardData.text)}
{this.renderPasteContent(
'Sanitized HTML',
(event.clipboardData as any).html
)}
{this.renderPasteContent('Original HTML', event.clipboardData.rawHtml)}
{this.renderPasteContent('Image', event.clipboardData.image, img => (
<img
ref={ref => ref && this.renderImage(ref, img)}
className={styles.img}
/>
))}
{this.renderPasteContent(
'LinkPreview',
event.clipboardData.linkPreview
? JSON.stringify(event.clipboardData.linkPreview)
: ''
)}
Paste from keyboard or native context menu:
{event.clipboardData.pasteNativeEvent ? ' true' : ' false'}
{getObjectKeys(event.clipboardData.customValues).map(contentType =>
this.renderPasteContent(
contentType,
event.clipboardData.customValues[contentType]
)
)}
</span>
);
case PluginEventType.PendingFormatStateChanged:
const formatState = event.formatState;
const keys = getObjectKeys(formatState);
return <span>{keys.map(key => `${key}=${event.formatState[key]}; `)}</span>;

case PluginEventType.EntityOperation:
const {
operation,
entity: { id, type },
} = event;
return (
<span>
Operation={EntityOperationMap[operation]} Type={type}; Id={id}
</span>
);

case PluginEventType.BeforeCutCopy:
const { isCut } = event;
return <span>isCut={isCut ? 'true' : 'false'}</span>;

case PluginEventType.EditImage:
return (
<>
<span>new src={event.newSrc.substr(0, 100)}</span>
</>
);

case PluginEventType.ZoomChanged:
return (
<span>
Old value={event.oldZoomScale} New value={event.newZoomScale}
</span>
);

case PluginEventType.BeforeKeyboardEditing:
return <span>Key code={event.rawEvent.which}</span>;

default:
return null;
}
}

private clear = () => {
this.events = [];
this.setState({
currentIndex: -1,
});
};

private renderImage = (img: HTMLImageElement, imageFile: File) => {
readFile(imageFile, dataUrl => (img.src = dataUrl));
};

private onDisplayCountChanged = () => {
let value = parseInt(this.displayCount.current.value);
this.setState({
displayCount: value,
});
};

private renderPasteContent(
title: string,
content: any,
renderer: (content: any) => JSX.Element = content => <span>{content}</span>
): JSX.Element {
return (
content && (
<details>
<summary>{title}</summary>
<div className={styles.pasteContent}>{renderer(content)}</div>
</details>
)
);
}

private getHtml(fragment: DocumentFragment) {
const stringArray: string[] = [];
for (let child = fragment.firstChild; child; child = child.nextSibling) {
stringArray.push(
safeInstanceOf(child, 'HTMLElement')
? child.outerHTML
: safeInstanceOf(child, 'Text')
? child.nodeValue
: ''
);
}

return stringArray.join('');
}
}
Loading