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

#407: Brought the feature allowing users to type in tight spots around block widgets #6794

Merged
merged 67 commits into from
May 14, 2020
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
690b7ba
The initial implementation of the widget type around feature.
oleq May 7, 2020
e022336
Created a manual test for the widget type around feature.
oleq May 7, 2020
727514e
Added the button icon file for the type around feature.
oleq May 7, 2020
0773651
Made the .ck-horizontal-line use `display: flow-root` to get rid of o…
oleq May 7, 2020
4a53d8e
Set `position: relative` on all widgets to allow the type around feat…
oleq May 7, 2020
70aa784
Excluded the "return-arrow" icon from the clean-up-svg-icons task to …
oleq May 7, 2020
449b1ef
Extracted hsl() coordinates of various color custom properties so the…
oleq May 7, 2020
1bf5f34
Enabled the WidgetTypeAround plugin as a dependency of the Widget plu…
oleq May 7, 2020
300e5ff
Adjusted type around icon color when editing root it blurred. Bound v…
oleq May 8, 2020
bbe23f2
Widget selection handle should change its color when the widget is no…
oleq May 8, 2020
47ce7c5
Docs.
oleq May 8, 2020
c917635
Fix: Clicking a type around button in a caption-less image widget sho…
oleq May 8, 2020
99b8063
Tests: Added MediaEmbed to the TypeAround manual test.
oleq May 8, 2020
baab447
Fix: The media embed attribute:url:media converter should not purge t…
oleq May 8, 2020
575a8de
Fix: The type around buttons should be aligned symmetrically.
oleq May 8, 2020
88acf31
Removed line support and mouseover/out activation for the MVP.
oleq May 8, 2020
0164bbc
Simplified the icon rendering inside insert paragraph buttons.
oleq May 8, 2020
a41ace9
Fix: Don't add classes to inline widgets.
oleq May 8, 2020
48c1d41
Added labels to buttons.
oleq May 8, 2020
707fdaf
Tests: Added tests for the WidgetTypeAround plugin.
oleq May 11, 2020
cb3c9ad
Tests: Aligned existing widget test to the presence of the type aroun…
oleq May 11, 2020
8e55923
Tests: Aligned image tests to the presence of type around feature in …
oleq May 11, 2020
17a9dfa
Docs: Documented the WidgetTypeAround plugin and its utils.
oleq May 11, 2020
1d78977
Refac: Removed dead code from widget type around utils.
oleq May 11, 2020
251329c
Merge branch 'master' into i/407-simple
oleq May 11, 2020
8db6e66
Tests: Added manual test description.
oleq May 12, 2020
08abe32
Tests: Added media embed conversion test to make sure it does not int…
oleq May 12, 2020
67d7c94
Tests: Added a test to make sure Widget requires WidgetTypeAround.
oleq May 12, 2020
897accd
Renamed `WidgetTypeAround#typeAround` -> `WidgetTypeAround#_insertPar…
oleq May 12, 2020
c0d48e0
Added missing dev dependencies to package.json.
oleq May 12, 2020
8c62940
Split the type around styles and moved the theme subset to ckeditor5-…
oleq May 12, 2020
6ec9bf8
Fix: The insert paragraph button should not collide with a widget dra…
oleq May 12, 2020
0274197
Update packages/ckeditor5-widget/tests/manual/type-around.md
oleq May 13, 2020
ce6c339
Update packages/ckeditor5-widget/tests/manual/type-around.md
oleq May 13, 2020
6275452
Update packages/ckeditor5-widget/src/widgettypearound/widgettypearoun…
oleq May 13, 2020
fcf0c62
Updated table layout post-fixer to properly fix empty rows.
niegowski May 7, 2020
559c943
Code cleaning - removed redundant check.
niegowski May 7, 2020
dfee50e
Table layout post-fixer updated to remove empty rows.
niegowski May 8, 2020
59e85a7
Table row upcast converter skips empty rows.
niegowski May 8, 2020
fddac60
Added missing wasFixed flag in post-fixer. Added CK_DEBUG_TABLE to ta…
niegowski May 9, 2020
126bd23
Rename empty table row upcast converter.
jodator May 12, 2020
475e37b
Internal: Updated dependencies.
mlewand May 13, 2020
a47fa58
Internal: Updated dependencies.
mlewand May 13, 2020
9b64464
Table heading rows should be properly updated after removing rows as …
niegowski May 7, 2020
e7d528c
Merging cells and removing empty rows in one batch.
niegowski May 8, 2020
c175288
Updating heading rows in one enqueued change block (to use the curren…
niegowski May 11, 2020
3d4bbc0
Apply suggestions from code review
niegowski May 12, 2020
528ab6d
Added the edge case test of removing multiple empty rows after cells …
niegowski May 12, 2020
71200d3
The table properties button should not be enabled if all cell propert…
niegowski May 7, 2020
ed24dad
Table properties button should be disabled if all related commands ar…
niegowski May 12, 2020
7ef6fe7
Added missing entries to contexts.json.
oleq May 13, 2020
9a4a2a9
Docs: Fixed wrong documentation of internal helpers inside the Widget…
oleq May 13, 2020
381bcda
Update packages/ckeditor5-widget/tests/widgettypearound/widgettypearo…
oleq May 13, 2020
bc96819
Update packages/ckeditor5-widget/tests/widgettypearound/widgettypearo…
oleq May 13, 2020
7821760
Tests: Clean-up in Widget tests.
oleq May 13, 2020
9b500fc
Docs: Made WidgetTypeAround#_insertParagraph a protected method becau…
oleq May 13, 2020
2b71a87
Removed an obsolete custom property from widget styles.
oleq May 13, 2020
188fa1a
Merge branch 'master' into i/407-simple
Reinmar May 14, 2020
3c842ec
Update packages/ckeditor5-widget/src/widgettypearound/widgettypearoun…
oleq May 14, 2020
4a9d28f
Made the insert paragraph button titles less technical and more user-…
oleq May 14, 2020
c92b4dc
Update packages/ckeditor5-widget/src/widgettypearound/widgettypearoun…
oleq May 14, 2020
7a3c53e
Simplified the insert icon parsing and delivery.
oleq May 14, 2020
d843063
Used the DowncastWriter instance from the conversionApi to avoid nest…
oleq May 14, 2020
c06cb6e
Tests: Updated widget type around tests to the new button titles.
oleq May 14, 2020
eb42ca5
Improved the performance of the view post-fixer by keeping track of w…
oleq May 14, 2020
e851b9e
Docs: Flattened API docs structure for widget/widgettypearound.
oleq May 14, 2020
4fbd1a8
Merge branch 'master' into i/407-simple
Reinmar May 14, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

.ck-editor__editable .ck-horizontal-line {
/* Necessary to render properly next to floated objects, e.g. side image case. */
overflow: hidden;
display: flow-root;
}

.ck-content hr {
Expand Down
52 changes: 41 additions & 11 deletions packages/ckeditor5-image/tests/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,13 @@ describe( 'Image', () => {
setModelData( model, '[<image alt="alt text" src="/assets/sample.png"></image>]' );

expect( getViewData( view ) ).to.equal(
'[<figure class="ck-widget ck-widget_selected image" contenteditable="false">' +
'[<figure class="' +
'ck-widget ' +
'ck-widget_can-type-around_after ck-widget_can-type-around_before ' +
'ck-widget_selected image" contenteditable="false"' +
'>' +
'<img alt="alt text" src="/assets/sample.png"></img>' +
'<div class="ck ck-reset_all ck-widget__type-around"></div>' +
'</figure>]'
);

Expand All @@ -75,8 +80,13 @@ describe( 'Image', () => {
setModelData( model, '[<image src="/assets/sample.png" alt=""></image>]' );

expect( getViewData( view ) ).to.equal(
'[<figure class="ck-widget ck-widget_selected image" contenteditable="false">' +
'<img alt="" src="/assets/sample.png"></img>' +
'[<figure class="' +
'ck-widget ' +
'ck-widget_can-type-around_after ck-widget_can-type-around_before ' +
'ck-widget_selected image" contenteditable="false"' +
'>' +
'<img alt="" src="/assets/sample.png"></img>' +
'<div class="ck ck-reset_all ck-widget__type-around"></div>' +
'</figure>]'
);

Expand All @@ -91,11 +101,21 @@ describe( 'Image', () => {
);

expect( getViewData( view ) ).to.equal(
'[<figure class="ck-widget ck-widget_selected image" contenteditable="false">' +
'<img alt="alt text" src="/assets/sample.png"></img>' +
'[<figure class="' +
'ck-widget ' +
'ck-widget_can-type-around_after ck-widget_can-type-around_before ' +
'ck-widget_selected image" contenteditable="false"' +
'>' +
'<img alt="alt text" src="/assets/sample.png"></img>' +
'<div class="ck ck-reset_all ck-widget__type-around"></div>' +
'</figure>]' +
'<figure class="ck-widget image" contenteditable="false">' +
'<img alt="alt text" src="/assets/sample.png"></img>' +
'<figure class="' +
'ck-widget ' +
'ck-widget_can-type-around_after ck-widget_can-type-around_before ' +
'image" contenteditable="false"' +
'>' +
'<img alt="alt text" src="/assets/sample.png"></img>' +
'<div class="ck ck-reset_all ck-widget__type-around"></div>' +
'</figure>'
);

Expand All @@ -105,11 +125,21 @@ describe( 'Image', () => {
} );

expect( getViewData( view ) ).to.equal(
'<figure class="ck-widget image" contenteditable="false">' +
'<img alt="alt text" src="/assets/sample.png"></img>' +
'<figure class="' +
'ck-widget ' +
'ck-widget_can-type-around_after ck-widget_can-type-around_before ' +
'image" contenteditable="false"' +
'>' +
'<img alt="alt text" src="/assets/sample.png"></img>' +
'<div class="ck ck-reset_all ck-widget__type-around"></div>' +
'</figure>' +
'[<figure class="ck-widget ck-widget_selected image" contenteditable="false">' +
'<img alt="alt text" src="/assets/sample.png"></img>' +
'[<figure class="' +
'ck-widget ' +
'ck-widget_can-type-around_after ck-widget_can-type-around_before ' +
'ck-widget_selected image" contenteditable="false"' +
'>' +
'<img alt="alt text" src="/assets/sample.png"></img>' +
'<div class="ck ck-reset_all ck-widget__type-around"></div>' +
'</figure>]'
);
} );
Expand Down
2 changes: 1 addition & 1 deletion packages/ckeditor5-image/tests/imageresize.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ describe( 'ImageResize', () => {
const resizerPosition = 'bottom-left';
const domParts = getWidgetDomParts( editor, widget, resizerPosition );
const initialPointerPosition = getHandleCenterPoint( domParts.widget, resizerPosition );
const resizeWrapperView = widget.getChild( 1 );
const resizeWrapperView = widget.getChild( 2 );

resizerMouseSimulator.down( editor, domParts.resizeHandle );

Expand Down
6 changes: 4 additions & 2 deletions packages/ckeditor5-media-embed/src/converters.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ export function modelToViewUrlAttributeConverter( registry, options ) {
const url = data.attributeNewValue;
const viewWriter = conversionApi.writer;
const figure = conversionApi.mapper.toViewElement( data.item );
const mediaContentElement = [ ...figure.getChildren() ]
.find( child => child.getCustomProperty( 'media-content' ) );

// TODO: removing it and creating it from scratch is a hack. We can do better than that.
viewWriter.remove( viewWriter.createRangeIn( figure ) );
// TODO: removing the wrapper and creating it from scratch is a hack. We can do better than that.
viewWriter.remove( mediaContentElement );

const mediaViewElement = registry.getMediaViewElement( viewWriter, url, options );

Expand Down
9 changes: 7 additions & 2 deletions packages/ckeditor5-media-embed/src/mediaregistry.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ class Media {
*/
getViewElement( writer, options ) {
const attributes = {};
let viewElement;

if ( options.renderForEditingView || ( options.renderMediaPreview && this.url && this._previewRenderer ) ) {
if ( this.url ) {
Expand All @@ -233,7 +234,7 @@ class Media {

const mediaHtml = this._getPreviewHtml( options );

return writer.createUIElement( 'div', attributes, function( domDocument ) {
viewElement = writer.createUIElement( 'div', attributes, function( domDocument ) {
const domElement = this.toDomElement( domDocument );

domElement.innerHTML = mediaHtml;
Expand All @@ -245,8 +246,12 @@ class Media {
attributes.url = this.url;
}

return writer.createEmptyElement( 'oembed', attributes );
viewElement = writer.createEmptyElement( 'oembed', attributes );
}

writer.setCustomProperty( 'media-content', true, viewElement );

return viewElement;
}

/**
Expand Down
42 changes: 42 additions & 0 deletions packages/ckeditor5-media-embed/tests/mediaembedediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,48 @@ describe( 'MediaEmbedEditing', () => {
'</figure>'
);
} );

// Related to https://github.com/ckeditor/ckeditor5/issues/407.
it( 'should not discard internals (e.g. UI) injected by other features when converting the url attribute', () => {
setModelData( model, '<media url="https://ckeditor.com"></media>' );
const media = doc.getRoot().getChild( 0 );

editor.editing.view.change( writer => {
const widgetViewElement = editor.editing.mapper.toViewElement( media );

const externalUIElement = writer.createUIElement( 'div', null, function( domDocument ) {
const domElement = this.toDomElement( domDocument );

domElement.innerHTML = 'external UI';

return domElement;
} );

writer.insert( writer.createPositionAt( widgetViewElement, 'end' ), externalUIElement );
} );

expect( getViewData( view, { withoutSelection: true, renderUIElements: true } ) ).to.equal(
'<figure class="ck-widget media" contenteditable="false">' +
'<div class="ck-media__wrapper" data-oembed-url="https://ckeditor.com">' +
'allow-everything, id=https://ckeditor.com' +
'</div>' +
'<div>external UI</div>' +
'</figure>'
);

model.change( writer => {
writer.setAttribute( 'url', 'https://cksource.com', media );
} );

expect( getViewData( view, { withoutSelection: true, renderUIElements: true } ) ).to.equal(
'<figure class="ck-widget media" contenteditable="false">' +
'<div class="ck-media__wrapper" data-oembed-url="https://cksource.com">' +
'allow-everything, id=https://cksource.com' +
'</div>' +
'<div>external UI</div>' +
'</figure>'
);
} );
} );
}
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

/* -- Generic colors ------------------------------------------------------------------------ */

--ck-color-focus-border: hsl(208, 79%, 51%);
--ck-color-focus-border-coordinates: 208, 79%, 51%;
oleq marked this conversation as resolved.
Show resolved Hide resolved
--ck-color-focus-border: hsl(var(--ck-color-focus-border-coordinates));
--ck-color-focus-outer-shadow: hsl(207, 89%, 86%);
--ck-color-focus-disabled-shadow: hsla(209, 90%, 72%,.3);
--ck-color-focus-error-shadow: hsla(9,100%,56%,.3);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

:root {
--ck-widget-type-around-button-size: 20px;
--ck-color-widget-type-around-button-active: var(--ck-color-focus-border);
--ck-color-widget-type-around-button-hover: var(--ck-color-widget-hover-border);
--ck-color-widget-type-around-button-blurred-editable: var(--ck-color-widget-blurred-border);
--ck-color-widget-type-around-button-radar-start-alpha: 0;
--ck-color-widget-type-around-button-radar-end-alpha: .3;
--ck-color-widget-type-around-button-icon: var(--ck-color-base-background);
}

.ck .ck-widget {
/*
* Styles of the type around buttons
*/
& .ck-widget__type-around__button {
cursor: pointer;
width: var(--ck-widget-type-around-button-size);
height: var(--ck-widget-type-around-button-size);
background: var(--ck-color-widget-type-around-button);
border-radius: 100px;
oleq marked this conversation as resolved.
Show resolved Hide resolved
animation: fadein linear 300ms 1 normal forwards;
transition: opacity 100ms linear;

& svg {
width: 10px;
height: 8px;
transform: translate(-50%,-50%);
transition: transform .5s ease;
margin-top: 1px;

& * {
stroke-dasharray: 10;
stroke-dashoffset: 0;

fill: none;
stroke: var(--ck-color-widget-type-around-button-icon);
stroke-width: 1.5px;
stroke-linecap: round;
stroke-linejoin: round;
}

& line {
stroke-dasharray: 7;
}
}

&:hover {
/*
* Display the "sonar" around the button when hovered.
*/
animation: ck-widget-type-around-button-sonar 1s ease infinite;

/*
* Animate active button's icon.
*/
& svg {
& polyline {
animation: ck-widget-type-around-arrow-dash 2s linear;
}

& line {
animation: ck-widget-type-around-arrow-tip-dash 2s linear;
}
}
}
}

/*
* Styles for the buttons when the widget is NOT selected (but the buttons are visible
* and still can be hovered).
*/
&:not(.ck-widget_selected) > .ck-widget__type-around > .ck-widget__type-around__button {
background: var(--ck-color-widget-type-around-button-hover);
}

/*
* Styles for the buttons when:
* - the widget is selected,
* - or the button is being hovered (regardless of the widget state).
*/
&.ck-widget_selected > .ck-widget__type-around > .ck-widget__type-around__button,
& > .ck-widget__type-around > .ck-widget__type-around__button:hover {
background: var(--ck-color-widget-type-around-button-active);

&::after {
width: calc(var(--ck-widget-type-around-button-size) - 2px);
height: calc(var(--ck-widget-type-around-button-size) - 2px);
border-radius: 100px;
background: linear-gradient(135deg, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,.3) 100%);
}
}

/*
* Styles for the "before" button when the widget has a selection handle. Because some space
* is consumed by the handle, the button must be moved slightly to the right to let it breathe.
*/
&.ck-widget_with-selection-handle > .ck-widget__type-around > .ck-widget__type-around__button_before {
margin-left: 20px;
}
}

/*
* Styles for the buttons when the widget is selected but the user clicked outside of the editor (blurred the editor).
*/
.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected > .ck-widget__type-around > .ck-widget__type-around__button:not(:hover) {
background: var(--ck-color-widget-type-around-button-blurred-editable);

& svg * {
stroke: hsl(0,0%,60%);
}
}

@keyframes ck-widget-type-around-arrow-dash {
0% {
stroke-dashoffset: 10;
}
20%, 100% {
stroke-dashoffset: 0;
}
}

@keyframes ck-widget-type-around-arrow-tip-dash {
0%, 20% {
stroke-dashoffset: 7;
}
40%, 100% {
stroke-dashoffset: 0;
}
}

@keyframes ck-widget-type-around-button-sonar {
0% {
box-shadow: 0 0 0 0 hsla(var(--ck-color-focus-border-coordinates), var(--ck-color-widget-type-around-button-radar-start-alpha));
}
50% {
box-shadow: 0 0 0 5px hsla(var(--ck-color-focus-border-coordinates), var(--ck-color-widget-type-around-button-radar-end-alpha));
}
100% {
box-shadow: 0 0 0 5px hsla(var(--ck-color-focus-border-coordinates), var(--ck-color-widget-type-around-button-radar-start-alpha));
}
}
4 changes: 3 additions & 1 deletion packages/ckeditor5-widget/lang/contexts.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"Widget toolbar": "The label used by assistive technologies describing a toolbar attached to a widget."
"Widget toolbar": "The label used by assistive technologies describing a toolbar attached to a widget.",
"Insert paragraph before widget": "The title displayed when a mouse is over a button that inserts a paragraph before a widget.",
"Insert paragraph after widget": "The title displayed when a mouse is over a button that inserts a paragraph after a widget."
}
2 changes: 2 additions & 0 deletions packages/ckeditor5-widget/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"@ckeditor/ckeditor5-enter": "^19.0.0",
"@ckeditor/ckeditor5-essentials": "^19.0.0",
"@ckeditor/ckeditor5-heading": "^19.0.0",
"@ckeditor/ckeditor5-horizontal-line": "^19.0.0",
"@ckeditor/ckeditor5-media-embed": "^19.0.0",
"@ckeditor/ckeditor5-paragraph": "^19.0.0",
"@ckeditor/ckeditor5-table": "^19.0.0",
"@ckeditor/ckeditor5-typing": "^19.0.0",
Expand Down
8 changes: 8 additions & 0 deletions packages/ckeditor5-widget/src/widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import MouseObserver from '@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver';
import WidgetTypeAround from './widgettypearound/widgettypearound';
import { getLabel, isWidget, WIDGET_SELECTED_CLASS_NAME } from './utils';
import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
import env from '@ckeditor/ckeditor5-utils/src/env';
Expand Down Expand Up @@ -38,6 +39,13 @@ export default class Widget extends Plugin {
return 'Widget';
}

/**
* @inheritDoc
*/
static get requires() {
return [ WidgetTypeAround ];
}

/**
* @inheritDoc
*/
Expand Down
Loading