Skip to content

Commit 210f317

Browse files
BryanValverdeUhaven2worldDurssjuliaroldiCopilot
authored
Bump RoosterJS to 9.33.0 (#3108)
* Fix toggling format issue at composition stage for CJK (#3064) * draft * temp * update ff * update * test * update * Avoid "undefined" in HTML to Markdown generated content (#3069) * fix: avoid "undefined" before paragraphs content * fix: set "image" as the default alt value instead of "undefined" --------- Co-authored-by: Francois Dursus <[email protected]> * Add focus handling in formatTableWithContentModel and its tests (#3072) * format applier (#3073) * Keep implicit paragraph when pressing Enter at the start of it. (#3075) * Enhance splitParagraph function to allow preservation of implicit paragraphs after split * Fix preserveImplicitParagraph flag in handleEnterOnParagraph to false * Update packages/roosterjs-content-model-plugins/lib/edit/utils/splitParagraph.ts Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]> * Add beforeLogicalRootChanged event handling and related tests (#3077) * Add beforeLogicalRootChanged event handling and related tests * Rename event type from 'beforeLogicalRootChanged' to 'beforeLogicalRootChange' across relevant files * Update packages/roosterjs-content-model-types/lib/event/LogicalRootChangedEvent.ts Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]> * Disable isComposing check in DOM event propagation for Android (#3076) * dsiable isComposing check for Android * add test --------- Co-authored-by: Bryan Valverde U <[email protected]> * Allow plugins to store state in snapshot (#3079) * Allow plugins to store custom state in undo snapshots * Type fixes * Move to using object instead array * Fix #3080 (#3084) * Add auto direction to setDirection (#3082) * Initial commit * Pending changes exported from your codespace * fix code and tests * Address comments --------- Co-authored-by: wisaulni <[email protected]> Co-authored-by: Bryan Valverde U <[email protected]> * Ensure image is loaded before creating image wrapper (#3090) * Enhance image loading handling in ImageEditPlugin to support resizing and editing of images not fully loaded * Apply suggestions from code review Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]> * test (#3092) * Fix #3085 (#3095) Co-authored-by: Julia Roldi <[email protected]> * Adjust the image wrapper to stay inline (#3093) Use text-bottom instead of bottom for vertical-align to prevent the image to rotate below the text line. Also add some 5px in margin bottom to compensate for the height of the bottom handles. * Fix 309357 (#3097) * Fix 309357 * improve * improve * improve * Update packages/roosterjs-content-model-types/lib/context/ModelToDomOption.ts Co-authored-by: Copilot <[email protected]> * Update packages/roosterjs-content-model-types/lib/context/ModelToDomSettings.ts Co-authored-by: Copilot <[email protected]> * fix build --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: Bryan Valverde U <[email protected]> * Fix #3063 (#3096) * Fix #3087 Delete paragraph styles when there is nothing else to be deleted (#3094) * Fix #3087 * Update packages/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteParagraphStyle.ts Co-authored-by: Copilot <[email protected]> * Update packages/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteParagraphStyle.ts Co-authored-by: Copilot <[email protected]> * Update packages/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteParagraphStyle.ts Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]> * Remove karma changes (#3102) * karma * change * Adjust Block Indentation (#3099) When inserting a list or table in an indented segment, add the indentation to the block. * Process non-visible elements (#3089) New parameter processNonVisibleElements has been added to the DomToModelSettings and DomToModelOptions, allowing optional processing of non-visible elements. * Fix runtime color for dark mode (#3101) * Fix runtime color for dark mode * add test * fix build * table rtl (#3103) The style direction: RTL does move the table to the right, so use justifySelf:flex-end. * image-handles (#3104) When rotating an image, the resize handles direction must be updated according to the rotation angle. * Fix superscript rule (#3106) * Update main version to 9.33.0 and remove overrides * Bump adapter * Fix 380860 (#3107) --------- Co-authored-by: Haowen Chen <[email protected]> Co-authored-by: François Dursus <[email protected]> Co-authored-by: Francois Dursus <[email protected]> Co-authored-by: Julia Roldi <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: Rain-Zheng <[email protected]> Co-authored-by: florian-msft <[email protected]> Co-authored-by: Jiuqing Song <[email protected]> Co-authored-by: wisaulni <[email protected]> Co-authored-by: wisaulni <[email protected]>
1 parent 45757fd commit 210f317

File tree

86 files changed

+2310
-164
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+2310
-164
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"Polski",
6464
"Popout",
6565
"Resizer",
66+
"resizers",
6667
"roosterjs",
6768
"rowspan",
6869
"saturationv",

demo/scripts/controlsV2/demoButtons/exportContentButton.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as DOMPurify from 'dompurify';
12
import { exportContent } from 'roosterjs-content-model-core';
23
import { ModelToTextCallbacks } from 'roosterjs-content-model-types';
34
import type { RibbonButton } from 'roosterjs-react';
@@ -33,12 +34,30 @@ export const exportContentButton: RibbonButton<ExportButtonStringKey> = {
3334
let html = '';
3435

3536
if (key == 'menuNameExportHTML') {
36-
html = exportContent(editor);
37+
html =
38+
'<html><head><style>p{margin-top:0;margin-bottom:0;}</style></head><body>' +
39+
exportContent(editor, 'HTML', {
40+
defaultContentModelFormatOverride: {
41+
p: {
42+
marginTop: '0',
43+
marginBottom: '0',
44+
},
45+
},
46+
}) +
47+
'</body></html>';
3748
} else if (key == 'menuNameExportText') {
3849
html = `<pre>${exportContent(editor, 'PlainText', callbacks)}</pre>`;
3950
}
4051

41-
win.document.write(editor.getTrustedHTMLHandler()(html));
52+
win.document.write(
53+
(DOMPurify.sanitize(html, {
54+
ADD_TAGS: ['head', 'meta', 'iframe'],
55+
ADD_ATTR: ['name', 'content'],
56+
WHOLE_DOCUMENT: true,
57+
ALLOW_UNKNOWN_PROTOCOLS: true,
58+
RETURN_TRUSTED_TYPE: true,
59+
}) as any) as string
60+
);
4261
},
4362
commandBarProperties: {
4463
buttonStyles: {

demo/scripts/controlsV2/demoButtons/formatPainterButton.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ export function createFormatPainterButton(
1212
key: 'formatPainter',
1313
unlocalizedText: 'Format painter',
1414
iconName: 'Brush',
15-
onClick: () => {
15+
onClick: editor => {
1616
handler.startFormatPainter();
17+
editor.focus();
1718
},
1819
};
1920
}

demo/scripts/controlsV2/mainPane/MainPane.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@
5252
top: 0;
5353
right: 0;
5454
bottom: 0;
55+
56+
p {
57+
margin-top: 0;
58+
margin-bottom: 0;
59+
}
5560
}
5661

5762
.resizer {

demo/scripts/controlsV2/mainPane/MainPane.tsx

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ApiPlaygroundPlugin } from '../sidePane/apiPlayground/ApiPlaygroundPlug
55
import { ContentModelPanePlugin } from '../sidePane/contentModel/ContentModelPanePlugin';
66
import { darkModeButton } from '../demoButtons/darkModeButton';
77
import { defaultDomToModelOption } from '../options/defaultDomToModelOption';
8+
import { defaultModelToDomOption } from '../options/defaultModelToDomOption';
89
import { Editor } from 'roosterjs-content-model-core';
910
import { EditorOptionsPlugin } from '../sidePane/editorOptions/EditorOptionsPlugin';
1011
import { EventViewPlugin } from '../sidePane/eventViewer/EventViewPlugin';
@@ -106,7 +107,6 @@ export class MainPane extends React.Component<{}, MainPaneState> {
106107
private formatPainterPlugin: FormatPainterPlugin;
107108
private samplePickerPlugin: SamplePickerPlugin;
108109
private snapshots: Snapshots;
109-
private imageEditPlugin: ImageEditPlugin;
110110
private markdownPanePlugin: MarkdownPanePlugin;
111111

112112
protected sidePane = React.createRef<SidePane>();
@@ -145,7 +145,6 @@ export class MainPane extends React.Component<{}, MainPaneState> {
145145
this.ribbonPlugin = createRibbonPlugin();
146146
this.formatPainterPlugin = new FormatPainterPlugin();
147147
this.samplePickerPlugin = new SamplePickerPlugin();
148-
this.imageEditPlugin = new ImageEditPlugin();
149148
this.markdownPanePlugin = new MarkdownPanePlugin();
150149

151150
this.state = {
@@ -167,13 +166,22 @@ export class MainPane extends React.Component<{}, MainPaneState> {
167166

168167
render() {
169168
const theme = getTheme(this.state.isDarkMode);
169+
170+
const imageEditPlugin = this.state.initState.pluginList.imageEditPlugin
171+
? new ImageEditPlugin({
172+
disableSideResize: this.state.initState.disableSideResize,
173+
})
174+
: null;
175+
170176
return (
171177
<ThemeProvider applyTo="body" theme={theme} className={styles.mainPane}>
172178
{this.renderTitleBar()}
173179
{!this.state.popoutWindow && this.renderTabs()}
174-
{!this.state.popoutWindow && this.renderRibbon()}
180+
{!this.state.popoutWindow && this.renderRibbon(imageEditPlugin)}
175181
<div className={styles.body + ' ' + (this.state.isDarkMode ? 'dark' : '')}>
176-
{this.state.popoutWindow ? this.renderPopout() : this.renderMainPane()}
182+
{this.state.popoutWindow
183+
? this.renderPopout(imageEditPlugin)
184+
: this.renderMainPane(imageEditPlugin)}
177185
</div>
178186
</ThemeProvider>
179187
);
@@ -303,13 +311,13 @@ export class MainPane extends React.Component<{}, MainPaneState> {
303311
</div>
304312
);
305313
}
306-
private renderRibbon() {
314+
private renderRibbon(imageEditPlugin: ImageEditPlugin | undefined) {
307315
return (
308316
<Ribbon
309317
buttons={getButtons(
310318
this.state.activeTab,
311319
this.formatPainterPlugin,
312-
this.imageEditPlugin
320+
imageEditPlugin
313321
)}
314322
plugin={this.ribbonPlugin}
315323
dir={this.state.isRtl ? 'rtl' : 'ltr'}
@@ -337,7 +345,7 @@ export class MainPane extends React.Component<{}, MainPaneState> {
337345
});
338346
}
339347

340-
private renderEditor() {
348+
private renderEditor(imageEditPlugin: ImageEditPlugin | undefined) {
341349
// Set preset if found
342350
const search = new URLSearchParams(document.location.search);
343351
const hasPreset = search.get('preset');
@@ -355,7 +363,7 @@ export class MainPane extends React.Component<{}, MainPaneState> {
355363
this.ribbonPlugin,
356364
this.formatPainterPlugin,
357365
this.samplePickerPlugin,
358-
...this.getToggleablePlugins(),
366+
...this.getToggleablePlugins(imageEditPlugin),
359367
this.contentModelPanePlugin.getInnerRibbonPlugin(),
360368
this.updateContentPlugin,
361369
];
@@ -389,17 +397,18 @@ export class MainPane extends React.Component<{}, MainPaneState> {
389397
this.state.initState.experimentalFeatures
390398
)}
391399
defaultDomToModelOptions={defaultDomToModelOption}
400+
defaultModelToDomOptions={defaultModelToDomOption}
392401
/>
393402
)}
394403
</div>
395404
</div>
396405
);
397406
}
398407

399-
private renderMainPane() {
408+
private renderMainPane(imageEditPlugin: ImageEditPlugin | undefined) {
400409
return (
401410
<>
402-
{this.renderEditor()}
411+
{this.renderEditor(imageEditPlugin)}
403412
{this.state.showSidePane ? (
404413
<>
405414
<div className={styles.resizer} onMouseDown={this.onMouseDown} />
@@ -425,7 +434,7 @@ export class MainPane extends React.Component<{}, MainPaneState> {
425434
);
426435
}
427436

428-
private renderPopout() {
437+
private renderPopout(imageEditPlugin: ImageEditPlugin | undefined) {
429438
return (
430439
<>
431440
{this.renderSidePane(true /*fullWidth*/)}
@@ -434,8 +443,10 @@ export class MainPane extends React.Component<{}, MainPaneState> {
434443
<ThemeProvider applyTo="body" theme={getTheme(this.state.isDarkMode)}>
435444
<div className={styles.mainPane}>
436445
{this.renderTabs()}
437-
{this.renderRibbon()}
438-
<div className={styles.body}>{this.renderEditor()}</div>
446+
{this.renderRibbon(imageEditPlugin)}
447+
<div className={styles.body}>
448+
{this.renderEditor(imageEditPlugin)}
449+
</div>
439450
</div>
440451
</ThemeProvider>
441452
</WindowProvider>,
@@ -501,7 +512,7 @@ export class MainPane extends React.Component<{}, MainPaneState> {
501512
];
502513
}
503514

504-
private getToggleablePlugins(): EditorPlugin[] {
515+
private getToggleablePlugins(imageEditPlugin: ImageEditPlugin | undefined): EditorPlugin[] {
505516
const {
506517
pluginList,
507518
allowExcelNoBorderTable,
@@ -515,6 +526,7 @@ export class MainPane extends React.Component<{}, MainPaneState> {
515526
customReplacements,
516527
editPluginOptions,
517528
} = this.state.initState;
529+
518530
return [
519531
pluginList.autoFormat && new AutoFormatPlugin(autoFormatOptions),
520532
pluginList.edit && new EditPlugin(editPluginOptions),
@@ -523,16 +535,17 @@ export class MainPane extends React.Component<{}, MainPaneState> {
523535
pluginList.tableEdit && new TableEditPlugin(),
524536
pluginList.watermark && new WatermarkPlugin(watermarkText),
525537
pluginList.markdown && new MarkdownPlugin(markdownOptions),
526-
pluginList.imageEditPlugin && this.imageEditPlugin,
538+
imageEditPlugin,
527539
pluginList.emoji && createEmojiPlugin(),
528540
pluginList.pasteOption && createPasteOptionPlugin(),
529541
pluginList.sampleEntity && new SampleEntityPlugin(),
530542
pluginList.contextMenu && createContextMenuPlugin(),
531543
pluginList.contextMenu && listMenu && createListEditMenuProvider(),
532544
pluginList.contextMenu && tableMenu && createTableEditMenuProvider(),
533545
pluginList.contextMenu &&
546+
imageEditPlugin &&
534547
imageMenu &&
535-
createImageEditMenuProvider(this.imageEditPlugin),
548+
createImageEditMenuProvider(imageEditPlugin),
536549
pluginList.hyperlink &&
537550
new HyperlinkPlugin(
538551
linkTitle?.indexOf(UrlPlaceholder) >= 0

demo/scripts/controlsV2/options/defaultDomToModelOption.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ export const defaultDomToModelOption: DomToModelOption = {
55
additionalFormatParsers: {
66
link: [demoUndeletableAnchorParser],
77
},
8+
processNonVisibleElements: true,
89
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { ModelToDomOption } from 'roosterjs-content-model-types';
2+
3+
export const defaultModelToDomOption: ModelToDomOption = {
4+
defaultContentModelFormatOverride: {
5+
p: {
6+
marginTop: '0',
7+
marginBottom: '0',
8+
},
9+
},
10+
};

demo/scripts/controlsV2/sidePane/editorOptions/EditorOptionsPlugin.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ const initialState: OptionState = {
6161
handleTabKey: true,
6262
},
6363
customReplacements: emojiReplacements,
64+
disableSideResize: false,
6465
experimentalFeatures: new Set<ExperimentalFeature>([
6566
'PersistCache',
6667
'HandleEnterKey',

demo/scripts/controlsV2/sidePane/editorOptions/OptionState.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export interface OptionState {
3838
markdownOptions: MarkdownOptions;
3939
customReplacements: CustomReplace[];
4040
editPluginOptions: EditOptions;
41+
disableSideResize: boolean;
4142

4243
// Legacy plugin options
4344
defaultFormat: ContentModelSegmentFormat;

demo/scripts/controlsV2/sidePane/editorOptions/OptionsPane.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ export class OptionsPane extends React.Component<OptionPaneProps, OptionState> {
141141
customReplacements: this.state.customReplacements,
142142
experimentalFeatures: this.state.experimentalFeatures,
143143
editPluginOptions: { ...this.state.editPluginOptions },
144+
disableSideResize: this.state.disableSideResize,
144145
};
145146

146147
if (callback) {

0 commit comments

Comments
 (0)