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

Initial implementation #1

Merged
merged 26 commits into from
Sep 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
de0e73f
Converters for the horizontal rule.
pomek Aug 28, 2019
b77824e
Added manual test.
pomek Aug 28, 2019
98f47be
Use selection handler for the editing element.
pomek Aug 28, 2019
f6fa712
Added a fake icon and introduced a command that adds the horizontal r…
pomek Aug 29, 2019
38bcb2f
Support for "HorizontalRuleCommand#isEnabled".
pomek Aug 29, 2019
3eeabdb
Added Webhook URL for notifications.
pomek Aug 29, 2019
63f23b6
Improved the manual test.
pomek Aug 29, 2019
1c1816f
Simplified the code.
pomek Aug 29, 2019
1bc930a
Added missing dependencies.
pomek Aug 29, 2019
3387151
Added horizontal rule icon.
Aug 30, 2019
4806bc0
After inserting a horizontal rule element, selection will be set on t…
pomek Sep 2, 2019
6abc437
<hr> element must be inserted in the editing view.
pomek Sep 2, 2019
f381c09
Simplified the code.
pomek Sep 2, 2019
9aa067e
Merge branch 't/ckeditor/1365' of github.com:ckeditor/ckeditor5-horiz…
pomek Sep 2, 2019
5c0aecc
Used `.ck-content` for styling horizontal-rule.
Sep 2, 2019
963e341
Simplified inserting the element.
pomek Sep 2, 2019
0a73ffa
Added tests.
pomek Sep 3, 2019
27e1f42
Improved the documentation of the plugin.
pomek Sep 3, 2019
98531ea
Added the "imageUpload" button to the toolbar.
pomek Sep 3, 2019
cf30a20
Changed a position of "horizontalRule" button in the toolbar.
pomek Sep 3, 2019
5ba4f8f
Changed ID of the snippet element.
pomek Sep 3, 2019
c973472
Simplified the implementation. Removed the "utils" file.
pomek Sep 3, 2019
474f3bd
Handle proper hr display next to elements with float property.
Sep 3, 2019
4b04d15
Use `.ck-content` styles for the <hr> element`.
Sep 5, 2019
5878495
Improved docs.
pomek Sep 5, 2019
12b9044
Merge branch 'master' into t/ckeditor/1365
pomek Sep 12, 2019
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
6 changes: 6 additions & 0 deletions docs/_snippets/features/horizontal-rule.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div id="snippet-horizontal-rule">
<h1>What is Lorem Ipsum?</h1>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry’s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
<hr>
<p>It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
</div>
61 changes: 61 additions & 0 deletions docs/_snippets/features/horizontal-rule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/* globals window, document, console */

import ClassicEditor from '@ckeditor/ckeditor5-build-classic/src/ckeditor';
Reinmar marked this conversation as resolved.
Show resolved Hide resolved
import HorizontalRule from '@ckeditor/ckeditor5-horizontal-rule/src/horizontalrule';
import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';

ClassicEditor.builtinPlugins.push( HorizontalRule );

ClassicEditor
.create( document.querySelector( '#snippet-horizontal-rule' ), {
toolbar: {
items: [
'heading',
'|',
'bold',
'italic',
'bulletedList',
'numberedList',
'blockQuote',
'link',
'|',
'imageUpload',
'mediaEmbed',
'insertTable',
'horizontalRule',
'|',
'undo',
'redo',
],
viewportTopOffset: window.getViewportTopOffsetConfig()
},
image: {
styles: [
'full',
'alignLeft',
'alignRight'
],
toolbar: [
'imageStyle:alignLeft',
'imageStyle:full',
'imageStyle:alignRight',
'|',
'imageTextAlternative'
]
},
table: {
contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ]
},
cloudServices: CS_CONFIG
} )
.then( editor => {
window.editor = editor;
} )
.catch( err => {
console.error( err.stack );
} );
34 changes: 34 additions & 0 deletions docs/api/horizontal-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
category: api-reference
---

# Horizontal rule feature for CKEditor 5

[![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-horizontal-rule.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-horizontal-rule)

This package implements the horizontal rule feature for CKEditor 5.

## Demo

Check out the {@link features/horizontal-rule#demo demo in the Horizontal rule feature} guide.

## Documentation

See the {@link features/horizontal-rule Horizontal rule feature} guide and the {@link module:horizontal-rule/horizontalrule~HorizontalRule} plugin documentation.

## Installation

```bash
npm install --save @ckeditor/ckeditor5-horizontal-rule
```

## Contribute

The source code of this package is available on GitHub in https://github.com/ckeditor/ckeditor5-horizontal-rule.

## External links

* [`@ckeditor/ckeditor5-horizontal-rule` on npm](https://www.npmjs.com/package/@ckeditor/ckeditor5-horizontal-rule)
* [`ckeditor/ckeditor5-horizontal-rule` on GitHub](https://github.com/ckeditor/ckeditor5-horizontal-rule)
* [Issue tracker](https://github.com/ckeditor/ckeditor5/issues)
* [Changelog](https://github.com/ckeditor/ckeditor5-horizontal-rule/blob/master/CHANGELOG.md)
55 changes: 55 additions & 0 deletions docs/features/horizontal-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
category: features
menu-title: Horizontal rule
---

# Horizontal rule

The {@link module:horizontal-rule/horizontalrule~HorizontalRule} plugin provides a possibility to insert a horizontal rule in the rich-text editor.

## Demo

Use the editor below to see the {@link module:horizontal-rule/horizontalrule~HorizontalRule} plugin in action.

{@snippet features/horizontal-rule}

## Installation

To add this feature to your rich-text editor, install the [`@ckeditor/ckeditor5-horizontal-rule`](https://www.npmjs.com/package/@ckeditor/ckeditor5-horizontal-rule) package:

```bash
npm install --save @ckeditor/ckeditor5-horizontal-rule
```

And add it to your plugin list configuration:

```js
import HorizontalRule from '@ckeditor/ckeditor5-horizontal-rule/src/horizontalrule';

ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ HorizontalRule, ... ],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toolbar: [ 'horizontalRule', ... ],
} )
.then( ... )
.catch( ... );
```

<info-box info>
Read more about {@link builds/guides/integration/installing-plugins installing plugins}.
</info-box>

## Common API

The {@link module:horizontal-rule/horizontalrule~HorizontalRule} plugin registers the UI button component (`'horizontalRule'`) and the `'horizontalRule'` command implemented by {@link module:horizontal-rule/horizontalrulecommand~HorizontalRuleCommand}.

The command can be executed using the {@link module:core/editor/editor~Editor#execute `editor.execute()`} method:

```js
// Inserts the horizontal rule to the selected content.
editor.execute( 'horizontalRule' );
```

## Contribute
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


The source code of the feature is available on GitHub in https://github.com/ckeditor/ckeditor5-horizontal-rule.
3 changes: 3 additions & 0 deletions lang/contexts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"Horizontal rule": "Horizontal rule"
}
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,16 @@
"ckeditor5-plugin"
],
"dependencies": {
"@ckeditor/ckeditor5-core": "^12.2.1",
"@ckeditor/ckeditor5-ui": "^14.0.0",
"@ckeditor/ckeditor5-widget": "^11.0.4"
},
"devDependencies": {
"@ckeditor/ckeditor5-cloud-services": "^11.0.5",
"@ckeditor/ckeditor5-editor-classic": "^12.1.3",
"@ckeditor/ckeditor5-easy-image": "^11.0.5",
"@ckeditor/ckeditor5-image": "^14.0.0",
"@ckeditor/ckeditor5-paragraph": "^11.0.5",
"eslint": "^5.5.0",
"eslint-config-ckeditor5": "^2.0.0",
"husky": "^1.3.1",
Expand Down
33 changes: 33 additions & 0 deletions src/horizontalrule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/**
* @module horizontal-rule/horizontalrule
*/

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import HorizontalRuleEditing from './horizontalruleediting';
import HorizontalRuleUI from './horizontalruleui';

/**
* The horizontal rule plugin provides a possibility to insert a horizontal rule in the rich-text editor.
*
* @extends module:core/plugin~Plugin
*/
export default class HorizontalRule extends Plugin {
/**
* @inheritDoc
*/
static get requires() {
return [ HorizontalRuleEditing, HorizontalRuleUI ];
}

/**
* @inheritDoc
*/
static get pluginName() {
return 'HorizontalRule';
}
}
98 changes: 98 additions & 0 deletions src/horizontalrulecommand.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/**
* @module horizontal-rule/horizontalrulecommand
*/

import Command from '@ckeditor/ckeditor5-core/src/command';
import { findOptimalInsertionPosition } from '@ckeditor/ckeditor5-widget/src/utils';

/**
* The insert a horizontal rule command.
*
* The command is registered by the {@link module:horizontal-rule/horizontalruleediting~HorizontalRuleEditing} as `'horizontalRule'`.
*
* To insert the horizontal rule at the current selection, execute the command:
*
* editor.execute( 'horizontalRule' );
*
* @extends module:core/command~Command
*/
export default class HorizontalRuleCommand extends Command {
/**
* @inheritDoc
*/
refresh() {
this.isEnabled = isHorizontalRuleAllowed( this.editor.model );
}

/**
* Executes the command.
*
* @fires execute
*/
execute() {
const model = this.editor.model;

model.change( writer => {
const modelElement = writer.createElement( 'horizontalRule' );

model.insertContent( modelElement );
} );
}
}

// Checks if the `horizontalRule` element can be inserted at current model selection.
//
// @param {module:engine/model/model~Model} model
// @returns {Boolean}
function isHorizontalRuleAllowed( model ) {
const schema = model.schema;
const selection = model.document.selection;

return isHorizontalRuleAllowedInParent( selection, schema, model ) &&
!checkSelectionOnObject( selection, schema );
}

// Checks if horizontal rule is allowed by schema in optimal insertion parent.
//
// @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
// @param {module:engine/model/schema~Schema} schema
// @param {module:engine/model/model~Model} model Model instance.
// @returns {Boolean}
function isHorizontalRuleAllowedInParent( selection, schema, model ) {
const parent = getInsertHorizontalRuleParent( selection, model );

return schema.checkChild( parent, 'horizontalRule' );
}

// Check if selection is on object.
//
// @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
// @param {module:engine/model/schema~Schema} schema
// @returns {Boolean}
function checkSelectionOnObject( selection, schema ) {
const selectedElement = selection.getSelectedElement();

return selectedElement && schema.isObject( selectedElement );
}

// Returns a node that will be used to insert horizontal rule with `model.insertContent` to check if horizontal rule can be placed there.
//
// @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
// @param {module:engine/model/model~Model} model Model instance.
// @returns {module:engine/model/element~Element}
function getInsertHorizontalRuleParent( selection, model ) {
const insertAt = findOptimalInsertionPosition( selection, model );

const parent = insertAt.parent;

if ( parent.isEmpty && !parent.is( '$root' ) ) {
return parent.parent;
}

return parent;
}
78 changes: 78 additions & 0 deletions src/horizontalruleediting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/**
* @module horizontal-rule/horizontalruleediting
*/

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import HorizontalRuleCommand from './horizontalrulecommand';
import { toWidget } from '@ckeditor/ckeditor5-widget/src/utils';

import '../theme/horizontalrule.css';

/**
* The horizontal rule editing feature.
*
* @extends module:core/plugin~Plugin
*/
export default class HorizontalRuleEditing extends Plugin {
/**
* @inheritDoc
*/
init() {
const editor = this.editor;
const schema = editor.model.schema;
const t = editor.t;
const conversion = editor.conversion;

schema.register( 'horizontalRule', {
isObject: true,
allowWhere: '$block'
} );

conversion.for( 'dataDowncast' ).elementToElement( {
model: 'horizontalRule',
view: ( modelElement, viewWriter ) => {
return viewWriter.createEmptyElement( 'hr' );
}
} );

conversion.for( 'editingDowncast' ).elementToElement( {
model: 'horizontalRule',
view: ( modelElement, viewWriter ) => {
const label = t( 'Horizontal rule' );
const viewWrapper = viewWriter.createContainerElement( 'div' );
const viewHrElement = viewWriter.createEmptyElement( 'hr' );

viewWriter.addClass( 'ck-horizontal-rule', viewWrapper );
viewWriter.setCustomProperty( 'hr', true, viewWrapper );

viewWriter.insert( viewWriter.createPositionAt( viewWrapper, 0 ), viewHrElement );

return toHorizontalRuleWidget( viewWrapper, viewWriter, label );
}
} );

conversion.for( 'upcast' ).elementToElement( { view: 'hr', model: 'horizontalRule' } );

editor.commands.add( 'horizontalRule', new HorizontalRuleCommand( editor ) );
}
}

// Converts a given {@link module:engine/view/element~Element} to a horizontal rule widget:
// * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to
// recognize the horizontal rule widget element.
// * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.
//
// @param {module:engine/view/element~Element} viewElement
// @param {module:engine/view/downcastwriter~DowncastWriter} writer An instance of the view writer.
// @param {String} label The element's label.
// @returns {module:engine/view/element~Element}
function toHorizontalRuleWidget( viewElement, writer, label ) {
writer.setCustomProperty( 'horizontalRule', true, viewElement );

return toWidget( viewElement, writer, { label } );
}
Loading