Skip to content

Commit

Permalink
Bump Rooster to 8.40.2 and ContentModel to 0.0.13 (#1522)
Browse files Browse the repository at this point in the history
* convert alpha to decimals

* fix auto format list

* add null and refactor

* Content Model Selection API step 4: Refactor existing table API (#1479)

* Selection API step 1

* Selection API 2

* New selection API

* Refactor table API

* add  test

* Support element with namespace (#1489)

* Content Model: Fix a bug when process margin (#1493)

* Fix margin issue

* Fix test

* Fix A tag without href (#1495)

* Fix Cut/Copy page scroll issue (#1496)

* Fix Cut/Copy page scroll issue

* Fix test

* fix image plugin z-index calc

* Content Model Format State Step 1: Refactor formatSegmentWithContentModel() (#1490)

* Selection API step 1

* Selection API 2

* New selection API

* Refactor table API

* add  test

* Format state step 1

* Improve

* update condition per comments

* Content Model Format State Step 2: Allow retrieving metadata directly (#1491)

* Selection API step 1

* Selection API 2

* New selection API

* Refactor table API

* add  test

* Format state step 1

* FormatState step 2

* Improve

* Content Model Format State Step 3: Add getFormatState API and ContentModelPlugin (#1492)

* Selection API step 1

* Selection API 2

* New selection API

* Refactor table API

* add  test

* Format state step 1

* FormatState step 2

* FormatState step 3: Add getFormatState API and ContentModel plugin

* Improve

* Improve

* Improve

* fix test

* improve, fix safari issue

* fix test

* Content Model: Add API clearFormat (#1497)

* Selection API step 1

* Selection API 2

* New selection API

* Refactor table API

* add  test

* Format state step 1

* FormatState step 2

* FormatState step 3: Add getFormatState API and ContentModel plugin

* Improve

* Content Model: clearFormat

* fix build

* Improve

* Improve

* fix test

* improve, fix safari issue

* fix test

* remove wrapper when content change

* fix

* Content Model: Move format API: link, image, captalization, ... (#1506)

* Selection API step 1

* Selection API 2

* New selection API

* Refactor table API

* add  test

* Format state step 1

* FormatState step 2

* FormatState step 3: Add getFormatState API and ContentModel plugin

* Improve

* Content Model: clearFormat

* fix build

* Improve

* Improve

* fix test

* improve, fix safari issue

* fix test

* ContentModel: Support insertLink and removeLink

* changeCapitalization and setImageAltText

* fix for image selection

* refactor

* refactor

* Fix #1509 (#1511)

* ContentModel: Improve Divider (#1513)

* ContentModel: Improve Divider

* Add BorderFormat to ContentModelBlockFormat

* Add test

* fix build

* Content Model: Support "no color" when set color (#1514)

* Content Model: Support "no color" when set color

* improve

* Content Model: Use Entity handle readonly element (#1515)

* Content Model: Support get and apply segment format (#1518)

* Do not merge table when insert a table (#1519)

* bump versions

* Content Model: Fix #1239 (#1521)

Co-authored-by: Júlia Roldi <[email protected]>
Co-authored-by: Jiuqing Song <[email protected]>
Co-authored-by: Julia Roldi <[email protected]>
Co-authored-by: Shai Petel <[email protected]>
Co-authored-by: Shai Petel <[email protected]>
  • Loading branch information
6 people authored Jan 20, 2023
1 parent 878b0d3 commit 962fb77
Show file tree
Hide file tree
Showing 145 changed files with 8,114 additions and 842 deletions.
21 changes: 15 additions & 6 deletions demo/scripts/controls/MainPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ import * as React from 'react';
import * as ReactDOM from 'react-dom';
import ApiPlaygroundPlugin from './sidePane/apiPlayground/ApiPlaygroundPlugin';
import BuildInPluginState from './BuildInPluginState';
import ContentModelPlugin from './sidePane/contentModel/ContentModelPlugin';
import ContentModelPanePlugin from './sidePane/contentModel/ContentModelPanePlugin';
import ContentModelRibbon from './ribbonButtons/contentModel/ContentModelRibbon';
import EditorOptionsPlugin from './sidePane/editorOptions/EditorOptionsPlugin';
import EventViewPlugin from './sidePane/eventViewer/EventViewPlugin';
import ExperimentalContentModelEditor from './editor/ExperimentalContentModelEditor';
import FormatPainterPlugin from './contentModel/plugins/FormatPainterPlugin';
import FormatStatePlugin from './sidePane/formatState/FormatStatePlugin';
import getToggleablePlugins from './getToggleablePlugins';
import MainPaneBase from './MainPaneBase';
import SidePane from './sidePane/SidePane';
import SnapshotPlugin from './sidePane/snapshot/SnapshotPlugin';
import TitleBar from './titleBar/TitleBar';
import { arrayPush } from 'roosterjs-editor-dom';
import { ContentModelPlugin } from 'roosterjs-content-model';
import { ContentModelRibbonPlugin } from './ribbonButtons/contentModel/ContentModelRibbonPlugin';
import { darkMode, DarkModeButtonStringKey } from './ribbonButtons/darkMode';
import { EditorOptions, EditorPlugin } from 'roosterjs-editor-types';
import { ExportButtonStringKey, exportContent } from './ribbonButtons/export';
Expand Down Expand Up @@ -118,13 +121,15 @@ class MainPane extends MainPaneBase {
private eventViewPlugin: EventViewPlugin;
private apiPlaygroundPlugin: ApiPlaygroundPlugin;
private snapshotPlugin: SnapshotPlugin;
private contentModelPlugin: ContentModelPlugin;
private ContentModelPanePlugin: ContentModelPanePlugin;
private ribbonPlugin: RibbonPlugin;
private contentModelRibbonPlugin: RibbonPlugin;
private pasteOptionPlugin: EditorPlugin;
private emojiPlugin: EditorPlugin;
private updateContentPlugin: UpdateContentPlugin;
private toggleablePlugins: EditorPlugin[] | null = null;
private contentModelPlugin: ContentModelPlugin;
private formatPainterPlugin: FormatPainterPlugin;
private mainWindowButtons: RibbonButton<RibbonStringKeys>[];
private popoutWindowButtons: RibbonButton<RibbonStringKeys>[];

Expand All @@ -140,12 +145,14 @@ class MainPane extends MainPaneBase {
this.eventViewPlugin = new EventViewPlugin();
this.apiPlaygroundPlugin = new ApiPlaygroundPlugin();
this.snapshotPlugin = new SnapshotPlugin();
this.contentModelPlugin = new ContentModelPlugin();
this.ContentModelPanePlugin = new ContentModelPanePlugin();
this.ribbonPlugin = createRibbonPlugin();
this.contentModelRibbonPlugin = createRibbonPlugin();
this.contentModelRibbonPlugin = new ContentModelRibbonPlugin();
this.pasteOptionPlugin = createPasteOptionPlugin();
this.emojiPlugin = createEmojiPlugin();
this.updateContentPlugin = createUpdateContentPlugin(UpdateMode.OnDispose, this.onUpdate);
this.contentModelPlugin = new ContentModelPlugin();
this.formatPainterPlugin = new FormatPainterPlugin();
this.mainWindowButtons = getButtons([
...AllButtonKeys,
darkMode,
Expand Down Expand Up @@ -417,7 +424,7 @@ class MainPane extends MainPaneBase {
this.eventViewPlugin,
this.apiPlaygroundPlugin,
this.snapshotPlugin,
this.contentModelPlugin,
this.ContentModelPanePlugin,
];
}

Expand All @@ -429,9 +436,11 @@ class MainPane extends MainPaneBase {
...this.toggleablePlugins,
this.ribbonPlugin,
this.contentModelRibbonPlugin,
this.contentModelPlugin.getInnerRibbonPlugin(),
this.ContentModelPanePlugin.getInnerRibbonPlugin(),
this.pasteOptionPlugin,
this.emojiPlugin,
this.contentModelPlugin,
this.formatPainterPlugin,
];

if (this.state.showSidePane || this.state.popoutWindow) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import { BackgroundColorFormatRenderer } from './formatPart/BackgroundColorFormatRenderer';
import { BorderFormatRenderers } from './formatPart/BorderFormatRenderers';
import { ContentModelBlockFormat, ContentModelSegmentFormat } from 'roosterjs-content-model';
import { DirectionFormatRenderers } from './formatPart/DirectionFormatRenderers';
import { FormatRenderer } from './utils/FormatRenderer';
Expand All @@ -16,6 +17,7 @@ const BlockFormatRenders: FormatRenderer<ContentModelBlockFormat>[] = [
PaddingFormatRenderer,
LineHeightFormatRenderer,
WhiteSpaceFormatRenderer,
...BorderFormatRenderers,
];

export function BlockFormatView(props: { format: ContentModelSegmentFormat }) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
.modelDivider {
background-color: #ccf;
background-color: #c0f;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
import * as React from 'react';
import { BlockFormatView } from '../format/BlockFormatView';
import { ContentModelDivider } from 'roosterjs-content-model';
import { BackgroundColorFormatRenderer } from '../format/formatPart/BackgroundColorFormatRenderer';
import { BorderFormatRenderers } from '../format/formatPart/BorderFormatRenderers';
import { ContentModelDivider, ContentModelDividerFormat } from 'roosterjs-content-model';
import { ContentModelView } from '../ContentModelView';
import { DirectionFormatRenderers } from '../format/formatPart/DirectionFormatRenderers';
import { DisplayFormatRenderer } from '../format/formatPart/DisplayFormatRenderer';
import { FormatRenderer } from '../format/utils/FormatRenderer';
import { FormatView } from '../format/FormatView';
import { LineHeightFormatRenderer } from '../format/formatPart/LineHeightFormatRenderer';
import { MarginFormatRenderer } from '../format/formatPart/MarginFormatRenderer';
import { PaddingFormatRenderer } from '../format/formatPart/PaddingFormatRenderer';
import { SizeFormatRenderers } from '../format/formatPart/SizeFormatRenderers';
import { useProperty } from '../../hooks/useProperty';
import { WhiteSpaceFormatRenderer } from '../format/formatPart/WhiteSpaceFormatRenderer';

const styles = require('./ContentModelDividerView.scss');
const DividerFormatRenders: FormatRenderer<ContentModelDividerFormat>[] = [
BackgroundColorFormatRenderer,
...DirectionFormatRenderers,
MarginFormatRenderer,
PaddingFormatRenderer,
LineHeightFormatRenderer,
WhiteSpaceFormatRenderer,
...BorderFormatRenderers,
DisplayFormatRenderer,
...SizeFormatRenderers,
];

export function ContentModelDividerView(props: { divider: ContentModelDivider }) {
const { divider } = props;
Expand All @@ -29,7 +50,7 @@ export function ContentModelDividerView(props: { divider: ContentModelDivider })
}, [tagName]);

const getFormat = React.useCallback(() => {
return <BlockFormatView format={divider.format} />;
return <FormatView format={divider.format} renderers={DividerFormatRenders} />;
}, [divider.format]);

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
import * as React from 'react';
import { BackgroundColorFormatRenderer } from '../format/formatPart/BackgroundColorFormatRenderer';
import { BlockFormatView } from '../format/BlockFormatView';
import { BlockGroupContentView } from './BlockGroupContentView';
import { BorderFormatRenderers } from '../format/formatPart/BorderFormatRenderers';
import { ContentModelView } from '../ContentModelView';
import { DirectionFormatRenderers } from '../format/formatPart/DirectionFormatRenderers';
import { FontFamilyFormatRenderer } from '../format/formatPart/FontFamilyFormatRenderer';
import { FontSizeFormatRenderer } from '../format/formatPart/FontSizeFormatRenderer';
import { FormatRenderer } from '../format/utils/FormatRenderer';
import { FormatView } from '../format/FormatView';
import { LineHeightFormatRenderer } from '../format/formatPart/LineHeightFormatRenderer';
import { MarginFormatRenderer } from '../format/formatPart/MarginFormatRenderer';
import { PaddingFormatRenderer } from '../format/formatPart/PaddingFormatRenderer';
import { TextColorFormatRenderer } from '../format/formatPart/TextColorFormatRenderer';
import { WhiteSpaceFormatRenderer } from '../format/formatPart/WhiteSpaceFormatRenderer';
import {
ContentModelQuote,
ContentModelQuoteFormat,
ContentModelSegmentFormat,
hasSelectionInBlock,
} from 'roosterjs-content-model';
Expand All @@ -27,15 +20,6 @@ import {

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

const QuoteBlockFormatRenders: FormatRenderer<ContentModelQuoteFormat>[] = [
BackgroundColorFormatRenderer,
...DirectionFormatRenderers,
MarginFormatRenderer,
PaddingFormatRenderer,
LineHeightFormatRenderer,
WhiteSpaceFormatRenderer,
...BorderFormatRenderers,
];
const QuoteSegmentFormatRenders: FormatRenderer<ContentModelSegmentFormat>[] = [
TextColorFormatRenderer,
FontSizeFormatRenderer,
Expand All @@ -54,7 +38,7 @@ export function ContentModelQuoteView(props: { quote: ContentModelQuote }) {
const getFormat = React.useCallback(() => {
return (
<>
<FormatView format={quote.format} renderers={QuoteBlockFormatRenders} />
<BlockFormatView format={quote.format} />
<FormatView
format={quote.quoteSegmentFormat}
renderers={QuoteSegmentFormatRenders}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { FormatView } from '../format/FormatView';
import { MetadataView } from '../format/MetadataView';
import { PaddingFormatRenderer } from '../format/formatPart/PaddingFormatRenderer';
import { TableCellMetadataFormatRender } from '../format/formatPart/TableCellMetadataFormatRender';
import { TextColorFormatRenderer } from '../format/formatPart/TextColorFormatRenderer';
import { updateTableCellMetadata } from 'roosterjs-content-model/lib/modelApi/metadata/updateTableCellMetadata';
import { useProperty } from '../../hooks/useProperty';
import { VerticalAlignFormatRenderer } from '../format/formatPart/VerticalAlignFormatRenderer';
Expand All @@ -30,6 +31,7 @@ const TableCellFormatRenderers: FormatRenderer<ContentModelTableCellFormat>[] =
PaddingFormatRenderer,
VerticalAlignFormatRenderer,
WordBreakFormatRenderer,
TextColorFormatRenderer,
];

export function ContentModelTableCellView(props: { cell: ContentModelTableCell }) {
Expand Down
71 changes: 71 additions & 0 deletions demo/scripts/controls/contentModel/plugins/FormatPainterPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { EditorPlugin, IEditor, PluginEvent, PluginEventType } from 'roosterjs-editor-types';
import {
applySegmentFormat,
ContentModelSegmentFormat,
getSegmentFormat,
IExperimentalContentModelEditor,
} from 'roosterjs-content-model';

const FORMATPAINTERCURSOR_SVG = require('./formatpaintercursor.svg');
const FORMATPAINTERCURSOR_STYLE = `;cursor: url("${FORMATPAINTERCURSOR_SVG}") 8.5 16, auto`;
const CURSOR_REGEX = /;?\s*cursor:\s*url\(\".*?\"\)[^;]*/gi;

interface FormatPainterFormatHolder {
format: ContentModelSegmentFormat | null;
}

export default class FormatPainterPlugin implements EditorPlugin {
private editor: IExperimentalContentModelEditor | null = null;

getName() {
return 'FormatPainter';
}

initialize(editor: IEditor) {
this.editor = editor as IExperimentalContentModelEditor;
}

dispose() {
this.editor = null;
}

onPluginEvent(event: PluginEvent) {
if (this.editor && event.eventType == PluginEventType.MouseUp) {
const formatHolder = getFormatHolder(this.editor);

if (formatHolder.format) {
applySegmentFormat(this.editor, formatHolder.format);
formatHolder.format = null;

setFormatPainterCursor(this.editor, false /*isOn*/);
}
}
}

static startFormatPainter(editor: IExperimentalContentModelEditor) {
const formatHolder = getFormatHolder(editor);
const format = getSegmentFormat(editor);

if (format) {
formatHolder.format = { ...format };
setFormatPainterCursor(editor, true /*isOn*/);
}
}
}

function getFormatHolder(editor: IEditor): FormatPainterFormatHolder {
return editor.getCustomData('__FormatPainterFormat', () => {
return {} as FormatPainterFormatHolder;
});
}

function setFormatPainterCursor(editor: IEditor, isOn: boolean) {
let styles = editor.getEditorDomAttribute('style') || '';
styles = styles.replace(CURSOR_REGEX, '');

if (isOn) {
styles += FORMATPAINTERCURSOR_STYLE;
}

editor.setEditorDomAttribute('style', styles);
}
22 changes: 22 additions & 0 deletions demo/scripts/controls/contentModel/plugins/formatpaintercursor.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 24 additions & 6 deletions demo/scripts/controls/editor/ExperimentalContentModelEditor.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { Editor } from 'roosterjs-editor-core';
import { EditorOptions, SelectionRangeTypes } from 'roosterjs-editor-types';
import {
getComputedStyles,
Position,
restoreContentWithEntityPlaceholder,
} from 'roosterjs-editor-dom';
import {
EditorContext,
ContentModelDocument,
ContentModelSegmentFormat,
contentModelToDom,
domToContentModel,
DomToModelOption,
EditorContext,
IExperimentalContentModelEditor,
ModelToDomOption,
} from 'roosterjs-content-model';
import {
getComputedStyles,
Position,
restoreContentWithEntityPlaceholder,
} from 'roosterjs-editor-dom';

/**
* !!! This is a temporary interface and will be removed in the future !!!
Expand All @@ -23,6 +24,7 @@ import {
export default class ExperimentalContentModelEditor extends Editor
implements IExperimentalContentModelEditor {
private getDarkColor: ((lightColor: string) => string) | undefined;
private pendingFormat: ContentModelSegmentFormat | null = null;

/**
* Creates an instance of ExperimentalContentModelEditor
Expand Down Expand Up @@ -88,4 +90,20 @@ export default class ExperimentalContentModelEditor extends Editor
this.select(range);
}
}

/**
* Get current pending format if any. A pending format is a format that user set when selection is collapsed,
* it will be applied when next time user input something
*/
getPendingFormat(): ContentModelSegmentFormat | null {
return this.pendingFormat;
}

/**
* Set current pending format if any. A pending format is a format that user set when selection is collapsed,
* it will be applied when next time user input something
*/
setPendingFormat(format: ContentModelSegmentFormat | null) {
this.pendingFormat = format;
}
}
Loading

0 comments on commit 962fb77

Please sign in to comment.