Skip to content

Commit

Permalink
Merge pull request #9263 from ckeditor/i/9104-caption-toolbar
Browse files Browse the repository at this point in the history
Feature (table): Added toolbar buttons for table captions. Closes #9104. Closes #9086. Closes #9304. Closes #9087. Closes #9088. Closes #9085.
  • Loading branch information
niegowski authored Apr 22, 2021
2 parents 1846a39 + 89f7743 commit 2d8fa7f
Show file tree
Hide file tree
Showing 24 changed files with 1,142 additions and 71 deletions.
52 changes: 52 additions & 0 deletions packages/ckeditor5-table/docs/features/table.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,25 @@ Put the caret anywhere inside the table and click the **"Table properties"** but
By default, table styling tools are not included in the {@link builds/guides/overview ready–to–use editor builds} and must be installed separately. See the [installation](#table-and-cell-styling-tools-2) section to learn how to enable them in your editor.
</info-box>

### Table caption

The {@link module:table/tablecaption~TableCaption} plugin adds support for table captions:

```html
<figure class="table">
<table>
<tr>
<td>...</td>
</tr>
</table>
<figcaption>A caption goes here...</figcaption>
</figure>
```

<info-box hint>
By default, the table caption is placed above the table. You can change the placement by setting [`caption-side`](https://developer.mozilla.org/en-US/docs/Web/CSS/caption-side) in your {@link builds/guides/integration/content-styles content styles} for the `.ck-content .table > figcaption` style. Changing it to `caption-side: bottom` will display the caption below the table.
</info-box>

## Table selection

The {@link module:table/tableselection~TableSelection} plugin introduces support for the custom selection system for tables that lets you:
Expand Down Expand Up @@ -121,6 +140,39 @@ ClassicEditor
Read more about {@link builds/guides/integration/installing-plugins installing plugins}.
</info-box>

### Table caption

To enable table caption feature in your editor, install the [`@ckeditor/ckeditor5-table`](https://www.npmjs.com/package/@ckeditor/ckeditor5-table) package:

```
npm install --save @ckeditor/ckeditor5-table
```

Then add the `Table`, `TableToolbar`, and **`TableCaption`** plugins to your plugin list and configure the table toolbar:

```js
import Table from '@ckeditor/ckeditor5-table/src/table';
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
import TableCaption from '@ckeditor/ckeditor5-table/src/tablecaption';

ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Table, TableToolbar, TableCaption, Bold, ... ],
toolbar: [ 'insertTable', ... ],
table: {
contentToolbar: [
'toggleTableCaption'
]
}
} )
.then( ... )
.catch( ... );
```

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

## Configuring styling tools

<info-box>
Expand Down
4 changes: 3 additions & 1 deletion packages/ckeditor5-table/lang/contexts.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,7 @@
"Align table to the right": "The label used by assistive technologies describing a button that aligns the table to the right.",
"The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\".": "The localized error string that can be displayed next to color (background, border) fields that have an invalid value",
"The value is invalid. Try \"10px\" or \"2em\" or simply \"2\".": "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value.",
"Color picker": "The label used by assistive technologies describing a button that opens a color picker, where user can choose a configured color for a certain properties (eg.: background color, color, border-color etc.)."
"Color picker": "The label used by assistive technologies describing a button that opens a color picker, where user can choose a configured color for a certain properties (eg.: background color, color, border-color etc.).",
"Toggle caption off": "The button label for the table toolbar hiding caption attached to the table.",
"Toggle caption on": "The button label for the table toolbar showing caption attached to the table."
}
5 changes: 2 additions & 3 deletions packages/ckeditor5-table/src/commands/insertcolumncommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ export default class InsertColumnCommand extends Command {
*/
refresh() {
const selection = this.editor.model.document.selection;
const isAnyCellSelected = !!getSelectionAffectedTableCells( selection ).length;

const tableParent = selection.getFirstPosition().findAncestor( 'table' );

this.isEnabled = !!tableParent;
this.isEnabled = isAnyCellSelected;
}

/**
Expand Down
5 changes: 2 additions & 3 deletions packages/ckeditor5-table/src/commands/insertrowcommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ export default class InsertRowCommand extends Command {
*/
refresh() {
const selection = this.editor.model.document.selection;
const isAnyCellSelected = !!getSelectionAffectedTableCells( selection ).length;

const tableParent = selection.getFirstPosition().findAncestor( 'table' );

this.isEnabled = !!tableParent;
this.isEnabled = isAnyCellSelected;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions packages/ckeditor5-table/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import TableCellPropertiesUI from './tablecellproperties/tablecellpropertiesui';
import TableProperties from './tableproperties';
import TablePropertiesEditing from './tableproperties/tablepropertiesediting';
import TablePropertiesUI from './tableproperties/tablepropertiesui';
import TableCaption from './tablecaption';
import TableCaptionEditing from './tablecaption/tablecaptionediting';
import TableCaptionUI from './tablecaption/tablecaptionui';
import TableClipboard from './tableclipboard';
import TableMouse from './tablemouse';
import TableKeyboard from './tablekeyboard';
Expand All @@ -34,6 +37,9 @@ export default {
TableProperties,
TablePropertiesEditing,
TablePropertiesUI,
TableCaption,
TableCaptionEditing,
TableCaptionUI,
TableMouse,
TableClipboard,
TableKeyboard,
Expand Down
5 changes: 4 additions & 1 deletion packages/ckeditor5-table/src/tablecaption.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

import { Plugin } from 'ckeditor5/src/core';
import TableCaptionEditing from './tablecaption/tablecaptionediting';
import TableCaptionUI from './tablecaption/tablecaptionui';

import '../theme/tablecaption.css';

/**
* The table caption plugin.
Expand All @@ -27,6 +30,6 @@ export default class TableCaption extends Plugin {
* @inheritDoc
*/
static get requires() {
return [ TableCaptionEditing ];
return [ TableCaptionEditing, TableCaptionUI ];
}
}
40 changes: 7 additions & 33 deletions packages/ckeditor5-table/src/tablecaption/tablecaptionediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
import { Plugin } from 'ckeditor5/src/core';
import { enablePlaceholder } from 'ckeditor5/src/engine';
import { toWidgetEditable } from 'ckeditor5/src/widget';

import injectTableCaptionPostFixer from '../converters/table-caption-post-fixer';
import ToggleTableCaptionCommand from './toggletablecaptioncommand';
import { isTable, matchTableCaptionViewElement } from './utils';

/**
* The table caption editing plugin.
Expand Down Expand Up @@ -46,6 +49,8 @@ export default class TableCaptionEditing extends Plugin {
} );
}

editor.commands.add( 'toggleTableCaption', new ToggleTableCaptionCommand( this.editor ) );

// View -> model converter for the data pipeline.
editor.conversion.for( 'upcast' ).elementToElement( {
view: matchTableCaptionViewElement,
Expand Down Expand Up @@ -78,7 +83,8 @@ export default class TableCaptionEditing extends Plugin {
enablePlaceholder( {
view,
element: figcaptionElement,
text: t( 'Enter table caption' )
text: t( 'Enter table caption' ),
keepOnFocus: true
} );

return toWidgetEditable( figcaptionElement, writer );
Expand All @@ -89,35 +95,3 @@ export default class TableCaptionEditing extends Plugin {
}
}

// {@link module:engine/view/matcher~Matcher} pattern. Checks if a given element is a caption.
//
// There are two possible forms of the valid caption:
// - A `<figcaption>` element inside a `<figure class="table">` element.
// - A `<caption>` inside a <table>.
//
// @private
// @param {module:engine/view/element~Element} element
// @returns {Object|null} Returns the object accepted by {@link module:engine/view/matcher~Matcher} or `null` if the element
// cannot be matched.
function matchTableCaptionViewElement( element ) {
const parent = element.parent;

if ( element.name == 'figcaption' && parent && parent.name == 'figure' && parent.hasClass( 'table' ) ) {
return { name: true };
}

if ( element.name == 'caption' && parent && parent.name == 'table' ) {
return { name: true };
}

return null;
}

// Checks if the provided model element is a `table`.
//
// @private
// @param {module:engine/model/element~Element} modelElement
// @returns {Boolean}
function isTable( modelElement ) {
return !!modelElement && modelElement.is( 'element', 'table' );
}
71 changes: 71 additions & 0 deletions packages/ckeditor5-table/src/tablecaption/tablecaptionui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/**
* @module table/tablecaption/tablecaptionui
*/

import { Plugin, icons } from 'ckeditor5/src/core';
import { ButtonView } from 'ckeditor5/src/ui';

import { getCaptionFromModelSelection } from './utils';

/**
* The table caption UI plugin. It introduces the `'toggleTableCaption'` UI button.
*
* @extends module:core/plugin~Plugin
*/
export default class TableCaptionUI extends Plugin {
/**
* @inheritDoc
*/
static get pluginName() {
return 'TableCaptionUI';
}

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

editor.ui.componentFactory.add( 'toggleTableCaption', locale => {
const command = editor.commands.get( 'toggleTableCaption' );
const view = new ButtonView( locale );

view.set( {
icon: icons.caption,
tooltip: true,
isToggleable: true
} );

view.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );
view.bind( 'label' ).to( command, 'value', value => value ? t( 'Toggle caption off' ) : t( 'Toggle caption on' ) );

this.listenTo( view, 'execute', () => {
editor.execute( 'toggleTableCaption', { focusCaptionOnShow: true } );

// Scroll to the selection and highlight the caption if the caption showed up.
if ( command.value ) {
const modelCaptionElement = getCaptionFromModelSelection( editor.model.document.selection );
const figcaptionElement = editor.editing.mapper.toViewElement( modelCaptionElement );

if ( !figcaptionElement ) {
return;
}

editingView.scrollToTheSelection();
editingView.change( writer => {
writer.addClass( 'table__caption_highlighted', figcaptionElement );
} );
}
} );

return view;
} );
}
}
Loading

0 comments on commit 2d8fa7f

Please sign in to comment.