-
Notifications
You must be signed in to change notification settings - Fork 167
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1487 from microsoft/u/juliaroldi/version-8.40.0
U/juliaroldi/version 8.40.0
- Loading branch information
Showing
129 changed files
with
9,081 additions
and
2,459 deletions.
There are no files selected for viewing
55 changes: 54 additions & 1 deletion
55
demo/scripts/controls/contentModel/components/model/ContentModelQuoteView.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,76 @@ | ||
import * as React from 'react'; | ||
import { BackgroundColorFormatRenderer } from '../format/formatPart/BackgroundColorFormatRenderer'; | ||
import { BlockGroupContentView } from './BlockGroupContentView'; | ||
import { ContentModelQuote, hasSelectionInBlock } from 'roosterjs-content-model'; | ||
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'; | ||
import { | ||
BoldFormatRenderer, | ||
ItalicFormatRenderer, | ||
UnderlineFormatRenderer, | ||
} from '../format/formatPart/BasicFormatRenderers'; | ||
|
||
const styles = require('./ContentModelQuoteView.scss'); | ||
|
||
const QuoteBlockFormatRenders: FormatRenderer<ContentModelQuoteFormat>[] = [ | ||
BackgroundColorFormatRenderer, | ||
...DirectionFormatRenderers, | ||
MarginFormatRenderer, | ||
PaddingFormatRenderer, | ||
LineHeightFormatRenderer, | ||
WhiteSpaceFormatRenderer, | ||
...BorderFormatRenderers, | ||
]; | ||
const QuoteSegmentFormatRenders: FormatRenderer<ContentModelSegmentFormat>[] = [ | ||
TextColorFormatRenderer, | ||
FontSizeFormatRenderer, | ||
FontFamilyFormatRenderer, | ||
BoldFormatRenderer, | ||
ItalicFormatRenderer, | ||
UnderlineFormatRenderer, | ||
]; | ||
|
||
export function ContentModelQuoteView(props: { quote: ContentModelQuote }) { | ||
const { quote } = props; | ||
const getContent = React.useCallback(() => { | ||
return <BlockGroupContentView group={quote} />; | ||
}, [quote]); | ||
|
||
const getFormat = React.useCallback(() => { | ||
return ( | ||
<> | ||
<FormatView format={quote.format} renderers={QuoteBlockFormatRenders} /> | ||
<FormatView | ||
format={quote.quoteSegmentFormat} | ||
renderers={QuoteSegmentFormatRenders} | ||
/> | ||
</> | ||
); | ||
}, [quote]); | ||
|
||
return ( | ||
<ContentModelView | ||
title="Quote" | ||
className={styles.modelQuote} | ||
hasSelection={hasSelectionInBlock(quote)} | ||
jsonSource={quote} | ||
getContent={getContent} | ||
getFormat={getFormat} | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
demo/scripts/controls/ribbonButtons/contentModel/blockQuoteButton.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import isContentModelEditor from '../../editor/isContentModelEditor'; | ||
import { QuoteButtonStringKey, RibbonButton } from 'roosterjs-react'; | ||
import { toggleBlockQuote } from 'roosterjs-content-model'; | ||
|
||
/** | ||
* @internal | ||
* "Block quote" button on the format ribbon | ||
*/ | ||
export const blockQuoteButton: RibbonButton<QuoteButtonStringKey> = { | ||
key: 'buttonNameQuote', | ||
unlocalizedText: 'Quote', | ||
iconName: 'RightDoubleQuote', | ||
isChecked: formatState => !!formatState.isBlockQuote, | ||
onClick: editor => { | ||
if (isContentModelEditor(editor)) { | ||
toggleBlockQuote(editor); | ||
} | ||
return true; | ||
}, | ||
}; |
45 changes: 45 additions & 0 deletions
45
demo/scripts/controls/ribbonButtons/contentModel/insertImageButton.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import isContentModelEditor from '../../editor/isContentModelEditor'; | ||
import { createElement } from 'roosterjs-editor-dom'; | ||
import { CreateElementData } from 'roosterjs-editor-types'; | ||
import { insertImage } from 'roosterjs-content-model'; | ||
import { InsertImageButtonStringKey, RibbonButton } from 'roosterjs-react'; | ||
|
||
const FileInput: CreateElementData = { | ||
tag: 'input', | ||
attributes: { | ||
type: 'file', | ||
accept: 'image/*', | ||
display: 'none', | ||
}, | ||
}; | ||
|
||
/** | ||
* @internal | ||
* "Insert image" button on the format ribbon | ||
*/ | ||
export const insertImageButton: RibbonButton<InsertImageButtonStringKey> = { | ||
key: 'buttonNameInsertImage', | ||
unlocalizedText: 'Insert image', | ||
iconName: 'Photo2', | ||
onClick: editor => { | ||
if (isContentModelEditor(editor)) { | ||
const document = editor.getDocument(); | ||
const fileInput = createElement(FileInput, document) as HTMLInputElement; | ||
document.body.appendChild(fileInput); | ||
|
||
fileInput.addEventListener('change', () => { | ||
if (fileInput.files) { | ||
for (let i = 0; i < fileInput.files.length; i++) { | ||
insertImage(editor, fileInput.files[i]); | ||
} | ||
} | ||
}); | ||
|
||
try { | ||
fileInput.click(); | ||
} finally { | ||
document.body.removeChild(fileInput); | ||
} | ||
} | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 33 additions & 15 deletions
48
packages/roosterjs-content-model/lib/domToModel/processors/quoteProcessor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,46 @@ | ||
import { addBlock } from '../../modelApi/common/addBlock'; | ||
import { ContentModelQuoteFormat } from '../../publicTypes/format/ContentModelQuoteFormat'; | ||
import { ContentModelSegmentFormat } from '../../publicTypes/format/ContentModelSegmentFormat'; | ||
import { createQuote } from '../../modelApi/creators/createQuote'; | ||
import { ElementProcessor } from '../../publicTypes/context/ElementProcessor'; | ||
import { getObjectKeys, getStyles } from 'roosterjs-editor-dom'; | ||
|
||
const KnownQuoteStyleNames = ['margin-top', 'margin-bottom']; | ||
import { getObjectKeys } from 'roosterjs-editor-dom'; | ||
import { knownElementProcessor } from './knownElementProcessor'; | ||
import { parseFormat } from '../utils/parseFormat'; | ||
import { stackFormat } from '../utils/stackFormat'; | ||
|
||
/** | ||
* @internal | ||
*/ | ||
export const quoteProcessor: ElementProcessor<HTMLQuoteElement> = (group, element, context) => { | ||
const styles = getStyles(element); | ||
if (element.style.borderLeft || element.style.borderRight) { | ||
stackFormat( | ||
context, | ||
{ | ||
paragraph: 'empty', | ||
segment: 'shallowCloneForBlock', | ||
}, | ||
() => { | ||
const quoteFormat: ContentModelQuoteFormat = {}; | ||
const segmentFormat: ContentModelSegmentFormat = {}; | ||
|
||
parseFormat(element, context.formatParsers.quote, quoteFormat, context); | ||
parseFormat(element, context.formatParsers.segmentOnBlock, segmentFormat, context); | ||
|
||
const quote = createQuote(quoteFormat, segmentFormat); | ||
|
||
addBlock(group, quote); | ||
|
||
if ( | ||
parseInt(element.style.marginTop) === 0 && | ||
parseInt(element.style.marginBottom) === 0 && | ||
getObjectKeys(styles).every(key => KnownQuoteStyleNames.indexOf(key) >= 0) | ||
) { | ||
// Temporary solution: Use Quote to provide indentation | ||
// TODO: We should use CSS to do indentation, and only use Quote for quoted text | ||
const quote = createQuote(); | ||
// These inline formats are overridden by quote, and will be applied onto BLOCKQUOTE element | ||
// So no need to pass them down into segments. | ||
// And when toggle blockquote (unwrap the quote model), no need to modify the inline format of segments | ||
getObjectKeys(segmentFormat).forEach(key => { | ||
delete context.segmentFormat[key]; | ||
}); | ||
|
||
addBlock(group, quote); | ||
context.elementProcessors.child(quote, element, context); | ||
context.elementProcessors.child(quote, element, context); | ||
} | ||
); | ||
} else { | ||
context.elementProcessors['*'](group, element, context); | ||
knownElementProcessor(group, element, context); | ||
} | ||
}; |
Oops, something went wrong.