-
Notifications
You must be signed in to change notification settings - Fork 158
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
Port Image Edit Operations #2670
Conversation
…u/juliaroldi/port-image
…u/juliaroldi/port-image
…u/juliaroldi/port-image
…t/roosterjs into u/juliaroldi/port-image
…t/roosterjs into u/juliaroldi/port-image
…t/roosterjs into u/juliaroldi/port-image
…om/microsoft/roosterjs into u/juliaroldi/image-edit-operations
|
||
/** | ||
* Start to crop selected image | ||
*/ | ||
cropImage(): void; | ||
cropImage(image: HTMLImageElement): void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of passing in the image, can we just use current selected image?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can, but I was following the pattern of ImageEditor interface
/** | ||
* Resize and rotate an image | ||
*/ | ||
| 'resizeAndRotate'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is this used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used when we right click an image and add the wrapper, can be removed for now.
@@ -56,7 +55,9 @@ export const setDOMSelection: SetDOMSelection = (core, selection, skipSelectionC | |||
core.api.setEditorStyle( | |||
core, | |||
DOM_SELECTION_CSS_KEY, | |||
`outline-style:auto!important; outline-color:${imageSelectionColor}!important;`, | |||
`outline-style:auto!important; outline-color:${imageSelectionColor}!important;display: ${ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems #2676 is caused by the outline-style here. Can we just fix it as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok.
@@ -56,7 +55,9 @@ export const setDOMSelection: SetDOMSelection = (core, selection, skipSelectionC | |||
core.api.setEditorStyle( | |||
core, | |||
DOM_SELECTION_CSS_KEY, | |||
`outline-style:auto!important; outline-color:${imageSelectionColor}!important;`, | |||
`outline-style:auto!important; outline-color:${imageSelectionColor}!important;display: ${ | |||
core.environment.isSafari ? 'inline-block' : 'inline-flex' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious, do we still need this check today?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need. :(
entryPoint?: string | ||
): HTMLImageElement { | ||
const parent = image.parentElement; | ||
// console.log(parent, entryPoint); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this
/** | ||
* @internal | ||
*/ | ||
export function getContentModelImage(editor: IEditor): ContentModelImage | null { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is this used? This will give you a cloned object but not the original image object. Is that ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used to get the image dataset
* @internal | ||
* Definition of ImageMetadataFormat | ||
*/ | ||
export const ImageMetadataFormatDefinition = createObjectDefinition<Required<ImageMetadataFormat>>({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this used externally?
} | ||
} | ||
|
||
public rotateImage(image: HTMLImageElement, angleRad: number) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add comment for public methods
) { | ||
editor.formatContentModel( | ||
(model, _) => { | ||
const selectedSegmentsAndParagraphs = getSelectedSegmentsAndParagraphs( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So here we edit image based on current selection, then why we need to pass in image object in other editing functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We pass the image element to add and remove the wrapper element. Here we edit the selected content model image
} | ||
|
||
public canRegenerateImage(image: HTMLImageElement): boolean { | ||
return canRegenerateImage(image) || canRegenerateImage(this.selectedImage); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be very confusing. It checks either the passed in image or current selection. We should make the function behavior predictable, only check one image
const selectedSegments = getSelectedSegments(model, false /*includeFormatHolder*/); | ||
if (selectedSegments.length == 1 && selectedSegments[0].segmentType == 'Image') { | ||
return selectedSegments[0]; | ||
return selectedSegments[0] as ContentModelImage; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine here, but if we do this kind of type cast in other place, it will be dangerous.
Actually, if you only want dataset, just get it directly from the connect model, and return the dataset instead.
Disconnected model actually need a clone, which is not as good perf as connected one.
function getSelectedImageDataset() {
let result;
editor.formatContentModel(model => {
const image = getSelectedImage(model);
result = getImageMetadata(image);
return false;
});
return result;
Something like this.
const paragraph = selectedSegmentsAndParagraphs[0][1]; | ||
|
||
if (paragraph && segment.segmentType == 'Image') { | ||
mutateSegment(paragraph, segment, image => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is nice.
And I think we only need to return true for formatContentModel
when image is really changed, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually you can move this down into the "if" block below.
`outline-style:auto!important; outline-color:${imageSelectionColor}!important;display: ${ | ||
core.environment.isSafari ? 'inline-block' : 'inline-flex' | ||
`outline-style:solid!important; outline-color:${imageSelectionColor}!important;display: ${ | ||
core.environment.isSafari ? '-webkit-inline-flex' : 'inline-flex' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool!
This change aims to Port Image edit operations from Image Edit plugin to Content Model Plugin. This feature is responsible for resize, rotate, crop, flip, resize by percentage and rotate by degree. This also removes the old Image Edit Plugin from demo site. The changes related to edit images with mouse selection will be done in a second PR.
Progress: