Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Merge pull request #5 from ckeditor/t/4
Browse files Browse the repository at this point in the history
Internal: The `WidgetEngine` plugin was merged into the `Widget` plugin. Closes #4.
  • Loading branch information
Reinmar authored Apr 3, 2017
2 parents 515aab6 + e3193ee commit 146c92d
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 157 deletions.
37 changes: 28 additions & 9 deletions src/widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,57 @@
*/

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import WidgetEngine from './widgetengine';
import MouseObserver from '@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver';
import ModelRange from '@ckeditor/ckeditor5-engine/src/model/range';
import ModelSelection from '@ckeditor/ckeditor5-engine/src/model/selection';
import ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';
import ViewEditableElement from '@ckeditor/ckeditor5-engine/src/view/editableelement';
import RootEditableElement from '@ckeditor/ckeditor5-engine/src/view/rooteditableelement';
import { isWidget } from './utils';
import { isWidget, WIDGET_SELECTED_CLASS_NAME, getLabel } from './utils';
import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';

import '../theme/theme.scss';

/**
* The widget plugin.
* Registers model to view selection converter for editing pipeline. It is hooked after default selection conversion.
* If converted selection is placed around widget element, selection is marked as fake. Additionally, proper CSS class
* is added to indicate that widget has been selected.
* Adds default {@link module:engine/view/document~Document#event:mousedown mousedown} handling on widget elements.
*
* @extends module:core/plugin~Plugin.
*/
export default class Widget extends Plugin {
/**
* @inheritDoc
*/
static get requires() {
return [ WidgetEngine ];
}

/**
* @inheritDoc
*/
init() {
const viewDocument = this.editor.editing.view;

let previouslySelected;

// Model to view selection converter.
// Converts selection placed over widget element to fake selection
this.editor.editing.modelToView.on( 'selection', ( evt, data, consumable, conversionApi ) => {
// Remove selected class from previously selected widget.
if ( previouslySelected && previouslySelected.hasClass( WIDGET_SELECTED_CLASS_NAME ) ) {
previouslySelected.removeClass( WIDGET_SELECTED_CLASS_NAME );
}

const viewSelection = conversionApi.viewSelection;

// Check if widget was clicked or some sub-element.
const selectedElement = viewSelection.getSelectedElement();

if ( !selectedElement || !isWidget( selectedElement ) ) {
return;
}

viewSelection.setFake( true, { label: getLabel( selectedElement ) } );
selectedElement.addClass( WIDGET_SELECTED_CLASS_NAME );
previouslySelected = selectedElement;
}, { priority: 'low' } );

// If mouse down is pressed on widget - create selection over whole widget.
viewDocument.addObserver( MouseObserver );
this.listenTo( viewDocument, 'mousedown', ( ...args ) => this._onMousedown( ...args ) );
Expand Down
50 changes: 0 additions & 50 deletions src/widgetengine.js

This file was deleted.

60 changes: 59 additions & 1 deletion tests/widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import ViewEditable from '@ckeditor/ckeditor5-engine/src/view/editableelement';
import DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata';
import AttributeContainer from '@ckeditor/ckeditor5-engine/src/view/attributeelement';
import { setData as setModelData, getData as getModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';

/* global document */
Expand All @@ -37,6 +38,10 @@ describe( 'Widget', () => {
doc.schema.registerItem( 'nested' );
doc.schema.allow( { name: '$inline', inside: 'nested' } );
doc.schema.allow( { name: 'nested', inside: 'widget' } );
doc.schema.registerItem( 'editable' );
doc.schema.allow( { name: '$inline', inside: 'editable' } );
doc.schema.allow( { name: 'editable', inside: 'widget' } );
doc.schema.allow( { name: 'editable', inside: '$root' } );

buildModelConverter().for( editor.editing.modelToView )
.fromElement( 'paragraph' )
Expand All @@ -48,7 +53,7 @@ describe( 'Widget', () => {
const b = new AttributeContainer( 'b' );
const div = new ViewContainer( 'div', null, b );

return toWidget( div );
return toWidget( div, { label: 'element label' } );
} );

buildModelConverter().for( editor.editing.modelToView )
Expand All @@ -58,6 +63,10 @@ describe( 'Widget', () => {
buildModelConverter().for( editor.editing.modelToView )
.fromElement( 'nested' )
.toElement( () => new ViewEditable( 'figcaption', { contenteditable: true } ) );

buildModelConverter().for( editor.editing.modelToView )
.fromElement( 'editable' )
.toElement( () => new ViewEditable( 'figcaption', { contenteditable: true } ) );
} );
} );

Expand Down Expand Up @@ -145,6 +154,55 @@ describe( 'Widget', () => {
expect( getModelData( doc ) ).to.equal( '[<widget></widget>]' );
} );

it( 'should apply fake view selection if model selection is on widget element', () => {
setModelData( doc, '[<widget>foo bar</widget>]' );

expect( getViewData( viewDocument ) ).to.equal(
'[<div class="ck-widget ck-widget_selected" contenteditable="false">foo bar<b></b></div>]'
);
expect( viewDocument.selection.isFake ).to.be.true;
} );

it( 'should use element\'s label to set fake selection if one is provided', () => {
setModelData( doc, '[<widget>foo bar</widget>]' );

expect( viewDocument.selection.fakeSelectionLabel ).to.equal( 'element label' );
} );

it( 'fake selection should be empty if widget is not selected', () => {
setModelData( doc, '<widget>foo bar</widget>' );

expect( viewDocument.selection.fakeSelectionLabel ).to.equal( '' );
} );

it( 'should toggle selected class', () => {
setModelData( doc, '[<widget>foo</widget>]' );

expect( getViewData( viewDocument ) ).to.equal(
'[<div class="ck-widget ck-widget_selected" contenteditable="false">foo<b></b></div>]'
);

doc.enqueueChanges( () => {
doc.selection.collapseToStart();
} );

expect( getViewData( viewDocument ) ).to.equal(
'[]<div class="ck-widget" contenteditable="false">foo<b></b></div>'
);
} );

it( 'should do nothing when selection is placed in other editable', () => {
setModelData( doc, '<widget><editable>foo bar</editable></widget><editable>[baz]</editable>' );

expect( getViewData( viewDocument ) ).to.equal(
'<div class="ck-widget" contenteditable="false">' +
'<figcaption contenteditable="true">foo bar</figcaption>' +
'<b></b>' +
'</div>' +
'<figcaption contenteditable="true">{baz}</figcaption>'
);
} );

describe( 'keys handling', () => {
describe( 'delete and backspace', () => {
test(
Expand Down
97 changes: 0 additions & 97 deletions tests/widgetengine.js

This file was deleted.

0 comments on commit 146c92d

Please sign in to comment.