tablecellpropertiesview.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /**
  6. * @module table/tablecellproperties/ui/tablecellpropertiesview
  7. */
  8. import View from '@ckeditor/ckeditor5-ui/src/view';
  9. import ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection';
  10. import submitHandler from '@ckeditor/ckeditor5-ui/src/bindings/submithandler';
  11. import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
  12. import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
  13. import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';
  14. import LabeledFieldView from '@ckeditor/ckeditor5-ui/src/labeledfield/labeledfieldview';
  15. import { createLabeledDropdown, createLabeledInputText } from '@ckeditor/ckeditor5-ui/src/labeledfield/utils';
  16. import LabelView from '@ckeditor/ckeditor5-ui/src/label/labelview';
  17. import { addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils';
  18. import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';
  19. import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
  20. import {
  21. fillToolbar,
  22. getBorderStyleDefinitions,
  23. getBorderStyleLabels,
  24. getLabeledColorInputCreator
  25. } from '../../ui/utils';
  26. import FormRowView from '../../ui/formrowview';
  27. import FormHeaderView from '../../ui/formheaderview';
  28. import checkIcon from '@ckeditor/ckeditor5-core/theme/icons/check.svg';
  29. import cancelIcon from '@ckeditor/ckeditor5-core/theme/icons/cancel.svg';
  30. import alignLeftIcon from '@ckeditor/ckeditor5-core/theme/icons/align-left.svg';
  31. import alignRightIcon from '@ckeditor/ckeditor5-core/theme/icons/align-right.svg';
  32. import alignCenterIcon from '@ckeditor/ckeditor5-core/theme/icons/align-center.svg';
  33. import alignJustifyIcon from '@ckeditor/ckeditor5-core/theme/icons/align-justify.svg';
  34. import alignTopIcon from '@ckeditor/ckeditor5-core/theme/icons/align-top.svg';
  35. import alignMiddleIcon from '@ckeditor/ckeditor5-core/theme/icons/align-middle.svg';
  36. import alignBottomIcon from '@ckeditor/ckeditor5-core/theme/icons/align-bottom.svg';
  37. import '../../../theme/form.css';
  38. import '../../../theme/tableform.css';
  39. import '../../../theme/tablecellproperties.css';
  40. const ALIGNMENT_ICONS = {
  41. left: alignLeftIcon,
  42. center: alignCenterIcon,
  43. right: alignRightIcon,
  44. justify: alignJustifyIcon,
  45. top: alignTopIcon,
  46. middle: alignMiddleIcon,
  47. bottom: alignBottomIcon
  48. };
  49. /**
  50. * The class representing a table cell properties form, allowing users to customize
  51. * certain style aspects of a table cell, for instance, border, padding, text alignment, etc..
  52. *
  53. * @extends module:ui/view~View
  54. */
  55. export default class TableCellPropertiesView extends View {
  56. /**
  57. * @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.
  58. * @param {Object} options Additional configuration of the view.
  59. * @param {module:table/table~TableColorConfig} options.borderColors A configuration of the border
  60. * color palette used by the
  61. * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#borderColorInput}.
  62. * @param {module:table/table~TableColorConfig} options.backgroundColors A configuration of the background
  63. * color palette used by the
  64. * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#backgroundInput}.
  65. */
  66. constructor( locale, options ) {
  67. super( locale );
  68. this.set( {
  69. /**
  70. * The value of the cell border style.
  71. *
  72. * @observable
  73. * @default ''
  74. * @member #borderStyle
  75. */
  76. borderStyle: '',
  77. /**
  78. * The value of the cell border width style.
  79. *
  80. * @observable
  81. * @default ''
  82. * @member #borderWidth
  83. */
  84. borderWidth: '',
  85. /**
  86. * The value of the cell border color style.
  87. *
  88. * @observable
  89. * @default ''
  90. * @member #borderColor
  91. */
  92. borderColor: '',
  93. /**
  94. * The value of the cell padding style.
  95. *
  96. * @observable
  97. * @default ''
  98. * @member #padding
  99. */
  100. padding: '',
  101. /**
  102. * The value of the cell background color style.
  103. *
  104. * @observable
  105. * @default ''
  106. * @member #backgroundColor
  107. */
  108. backgroundColor: '',
  109. /**
  110. * The value of the table cell width style.
  111. *
  112. * @observable
  113. * @default ''
  114. * @member #width
  115. */
  116. width: '',
  117. /**
  118. * The value of the table cell height style.
  119. *
  120. * @observable
  121. * @default ''
  122. * @member #height
  123. */
  124. height: '',
  125. /**
  126. * The value of the horizontal text alignment style.
  127. *
  128. * @observable
  129. * @default ''
  130. * @member #horizontalAlignment
  131. */
  132. horizontalAlignment: '',
  133. /**
  134. * The value of the vertical text alignment style.
  135. *
  136. * @observable
  137. * @default ''
  138. * @member #verticalAlignment
  139. */
  140. verticalAlignment: ''
  141. } );
  142. /**
  143. * Options passed to the view. See {@link #constructor} to learn more.
  144. *
  145. * @member {Object}
  146. */
  147. this.options = options;
  148. const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();
  149. const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();
  150. const { horizontalAlignmentToolbar, verticalAlignmentToolbar, alignmentLabel } = this._createAlignmentFields();
  151. /**
  152. * Tracks information about the DOM focus in the form.
  153. *
  154. * @readonly
  155. * @member {module:utils/focustracker~FocusTracker}
  156. */
  157. this.focusTracker = new FocusTracker();
  158. /**
  159. * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
  160. *
  161. * @readonly
  162. * @member {module:utils/keystrokehandler~KeystrokeHandler}
  163. */
  164. this.keystrokes = new KeystrokeHandler();
  165. /**
  166. * A collection of child views in the form.
  167. *
  168. * @readonly
  169. * @type {module:ui/viewcollection~ViewCollection}
  170. */
  171. this.children = this.createCollection();
  172. /**
  173. * A dropdown that allows selecting the style of the table cell border.
  174. *
  175. * @readonly
  176. * @member {module:ui/dropdown/dropdownview~DropdownView}
  177. */
  178. this.borderStyleDropdown = borderStyleDropdown;
  179. /**
  180. * An input that allows specifying the width of the table cell border.
  181. *
  182. * @readonly
  183. * @member {module:ui/inputtext/inputtextview~InputTextView}
  184. */
  185. this.borderWidthInput = borderWidthInput;
  186. /**
  187. * An input that allows specifying the color of the table cell border.
  188. *
  189. * @readonly
  190. * @member {module:table/ui/colorinputview~ColorInputView}
  191. */
  192. this.borderColorInput = borderColorInput;
  193. /**
  194. * An input that allows specifying the table cell background color.
  195. *
  196. * @readonly
  197. * @member {module:table/ui/colorinputview~ColorInputView}
  198. */
  199. this.backgroundInput = this._createBackgroundField();
  200. /**
  201. * An input that allows specifying the table cell padding.
  202. *
  203. * @readonly
  204. * @member {module:ui/inputtext/inputtextview~InputTextView}
  205. */
  206. this.paddingInput = this._createPaddingField();
  207. /**
  208. * An input that allows specifying the table cell width.
  209. *
  210. * @readonly
  211. * @member {module:ui/inputtext/inputtextview~InputTextView}
  212. */
  213. this.widthInput = widthInput;
  214. /**
  215. * An input that allows specifying the table cell height.
  216. *
  217. * @readonly
  218. * @member {module:ui/inputtext/inputtextview~InputTextView}
  219. */
  220. this.heightInput = heightInput;
  221. /**
  222. * A toolbar with buttons that allow changing the horizontal text alignment in a table cell.
  223. *
  224. * @readonly
  225. * @member {module:ui/toolbar/toolbar~ToolbarView}
  226. */
  227. this.horizontalAlignmentToolbar = horizontalAlignmentToolbar;
  228. /**
  229. * A toolbar with buttons that allow changing the vertical text alignment in a table cell.
  230. *
  231. * @readonly
  232. * @member {module:ui/toolbar/toolbar~ToolbarView}
  233. */
  234. this.verticalAlignmentToolbar = verticalAlignmentToolbar;
  235. // Defer creating to make sure other fields are present and the Save button can
  236. // bind its #isEnabled to their error messages so there's no way to save unless all
  237. // fields are valid.
  238. const { saveButtonView, cancelButtonView } = this._createActionButtons();
  239. /**
  240. * The "Save" button view.
  241. *
  242. * @member {module:ui/button/buttonview~ButtonView}
  243. */
  244. this.saveButtonView = saveButtonView;
  245. /**
  246. * The "Cancel" button view.
  247. *
  248. * @member {module:ui/button/buttonview~ButtonView}
  249. */
  250. this.cancelButtonView = cancelButtonView;
  251. /**
  252. * A collection of views that can be focused in the form.
  253. *
  254. * @readonly
  255. * @protected
  256. * @member {module:ui/viewcollection~ViewCollection}
  257. */
  258. this._focusables = new ViewCollection();
  259. /**
  260. * Helps cycling over {@link #_focusables} in the form.
  261. *
  262. * @readonly
  263. * @protected
  264. * @member {module:ui/focuscycler~FocusCycler}
  265. */
  266. this._focusCycler = new FocusCycler( {
  267. focusables: this._focusables,
  268. focusTracker: this.focusTracker,
  269. keystrokeHandler: this.keystrokes,
  270. actions: {
  271. // Navigate form fields backwards using the Shift + Tab keystroke.
  272. focusPrevious: 'shift + tab',
  273. // Navigate form fields forwards using the Tab key.
  274. focusNext: 'tab'
  275. }
  276. } );
  277. // Form header.
  278. this.children.add( new FormHeaderView( locale, {
  279. label: this.t( 'Cell properties' )
  280. } ) );
  281. // Border row.
  282. this.children.add( new FormRowView( locale, {
  283. labelView: borderRowLabel,
  284. children: [
  285. borderRowLabel,
  286. borderStyleDropdown,
  287. borderColorInput,
  288. borderWidthInput
  289. ],
  290. class: 'ck-table-form__border-row'
  291. } ) );
  292. // Background.
  293. this.children.add( new FormRowView( locale, {
  294. children: [
  295. this.backgroundInput
  296. ]
  297. } ) );
  298. // Dimensions row and padding.
  299. this.children.add( new FormRowView( locale, {
  300. children: [
  301. // Dimensions row.
  302. new FormRowView( locale, {
  303. labelView: dimensionsLabel,
  304. children: [
  305. dimensionsLabel,
  306. widthInput,
  307. operatorLabel,
  308. heightInput
  309. ],
  310. class: 'ck-table-form__dimensions-row'
  311. } ),
  312. // Padding row.
  313. new FormRowView( locale, {
  314. children: [
  315. this.paddingInput
  316. ],
  317. class: 'ck-table-cell-properties-form__padding-row'
  318. } )
  319. ]
  320. } ) );
  321. // Text alignment row.
  322. this.children.add( new FormRowView( locale, {
  323. labelView: alignmentLabel,
  324. children: [
  325. alignmentLabel,
  326. horizontalAlignmentToolbar,
  327. verticalAlignmentToolbar
  328. ],
  329. class: 'ck-table-cell-properties-form__alignment-row'
  330. } ) );
  331. // Action row.
  332. this.children.add( new FormRowView( locale, {
  333. children: [
  334. this.saveButtonView,
  335. this.cancelButtonView
  336. ],
  337. class: 'ck-table-form__action-row'
  338. } ) );
  339. this.setTemplate( {
  340. tag: 'form',
  341. attributes: {
  342. class: [
  343. 'ck',
  344. 'ck-form',
  345. 'ck-table-form',
  346. 'ck-table-cell-properties-form'
  347. ],
  348. // https://github.com/ckeditor/ckeditor5-link/issues/90
  349. tabindex: '-1'
  350. },
  351. children: this.children
  352. } );
  353. }
  354. /**
  355. * @inheritDoc
  356. */
  357. render() {
  358. super.render();
  359. // Enable the "submit" event for this view. It can be triggered by the #saveButtonView
  360. // which is of the "submit" DOM "type".
  361. submitHandler( {
  362. view: this
  363. } );
  364. [
  365. this.borderStyleDropdown,
  366. this.borderColorInput,
  367. this.borderWidthInput,
  368. this.backgroundInput,
  369. this.widthInput,
  370. this.heightInput,
  371. this.paddingInput,
  372. this.horizontalAlignmentToolbar,
  373. this.verticalAlignmentToolbar,
  374. this.saveButtonView,
  375. this.cancelButtonView
  376. ].forEach( view => {
  377. // Register the view as focusable.
  378. this._focusables.add( view );
  379. // Register the view in the focus tracker.
  380. this.focusTracker.add( view.element );
  381. } );
  382. // Mainly for closing using "Esc" and navigation using "Tab".
  383. this.keystrokes.listenTo( this.element );
  384. }
  385. /**
  386. * Focuses the fist focusable field in the form.
  387. */
  388. focus() {
  389. this._focusCycler.focusFirst();
  390. }
  391. /**
  392. * Creates the following form fields:
  393. *
  394. * * {@link #borderStyleDropdown},
  395. * * {@link #borderWidthInput},
  396. * * {@link #borderColorInput}.
  397. *
  398. * @private
  399. * @returns {Object.<String,module:ui/view~View>}
  400. */
  401. _createBorderFields() {
  402. const colorInputCreator = getLabeledColorInputCreator( {
  403. colorConfig: this.options.borderColors,
  404. columns: 5
  405. } );
  406. const locale = this.locale;
  407. const t = this.t;
  408. // -- Group label ---------------------------------------------
  409. const borderRowLabel = new LabelView( locale );
  410. borderRowLabel.text = t( 'Border' );
  411. // -- Style ---------------------------------------------------
  412. const styleLabels = getBorderStyleLabels( t );
  413. const borderStyleDropdown = new LabeledFieldView( locale, createLabeledDropdown );
  414. borderStyleDropdown.set( {
  415. label: t( 'Style' ),
  416. class: 'ck-table-form__border-style'
  417. } );
  418. borderStyleDropdown.fieldView.buttonView.set( {
  419. isOn: false,
  420. withText: true,
  421. tooltip: t( 'Style' )
  422. } );
  423. borderStyleDropdown.fieldView.buttonView.bind( 'label' ).to( this, 'borderStyle', value => {
  424. return styleLabels[ value ? value : 'none' ];
  425. } );
  426. borderStyleDropdown.fieldView.on( 'execute', evt => {
  427. this.borderStyle = evt.source._borderStyleValue;
  428. } );
  429. addListToDropdown( borderStyleDropdown.fieldView, getBorderStyleDefinitions( this ) );
  430. // -- Width ---------------------------------------------------
  431. const borderWidthInput = new LabeledFieldView( locale, createLabeledInputText );
  432. borderWidthInput.set( {
  433. label: t( 'Width' ),
  434. class: 'ck-table-form__border-width'
  435. } );
  436. borderWidthInput.fieldView.bind( 'value' ).to( this, 'borderWidth' );
  437. borderWidthInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );
  438. borderWidthInput.fieldView.on( 'input', () => {
  439. this.borderWidth = borderWidthInput.fieldView.element.value;
  440. } );
  441. // -- Color ---------------------------------------------------
  442. const borderColorInput = new LabeledFieldView( locale, colorInputCreator );
  443. borderColorInput.set( {
  444. label: t( 'Color' ),
  445. class: 'ck-table-form__border-color'
  446. } );
  447. borderColorInput.fieldView.bind( 'value' ).to( this, 'borderColor' );
  448. borderColorInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );
  449. borderColorInput.fieldView.on( 'input', () => {
  450. this.borderColor = borderColorInput.fieldView.value;
  451. } );
  452. // Reset the border color and width fields when style is "none".
  453. // https://github.com/ckeditor/ckeditor5/issues/6227
  454. this.on( 'change:borderStyle', ( evt, name, value ) => {
  455. if ( !isBorderStyleSet( value ) ) {
  456. this.borderColor = '';
  457. this.borderWidth = '';
  458. }
  459. } );
  460. return {
  461. borderRowLabel,
  462. borderStyleDropdown,
  463. borderColorInput,
  464. borderWidthInput
  465. };
  466. }
  467. /**
  468. * Creates the following form fields:
  469. *
  470. * * {@link #backgroundInput}.
  471. *
  472. * @private
  473. * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}
  474. */
  475. _createBackgroundField() {
  476. const locale = this.locale;
  477. const t = this.t;
  478. const colorInputCreator = getLabeledColorInputCreator( {
  479. colorConfig: this.options.backgroundColors,
  480. columns: 5
  481. } );
  482. const backgroundInput = new LabeledFieldView( locale, colorInputCreator );
  483. backgroundInput.set( {
  484. label: t( 'Background' ),
  485. class: 'ck-table-cell-properties-form__background'
  486. } );
  487. backgroundInput.fieldView.bind( 'value' ).to( this, 'backgroundColor' );
  488. backgroundInput.fieldView.on( 'input', () => {
  489. this.backgroundColor = backgroundInput.fieldView.value;
  490. } );
  491. return backgroundInput;
  492. }
  493. /**
  494. * Creates the following form fields:
  495. *
  496. * * {@link #widthInput}.
  497. * * {@link #heightInput}.
  498. *
  499. * @private
  500. * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}
  501. */
  502. _createDimensionFields() {
  503. const locale = this.locale;
  504. const t = this.t;
  505. // -- Label ---------------------------------------------------
  506. const dimensionsLabel = new LabelView( locale );
  507. dimensionsLabel.text = t( 'Dimensions' );
  508. // -- Width ---------------------------------------------------
  509. const widthInput = new LabeledFieldView( locale, createLabeledInputText );
  510. widthInput.set( {
  511. label: t( 'Width' ),
  512. class: 'ck-table-form__dimensions-row__width'
  513. } );
  514. widthInput.fieldView.bind( 'value' ).to( this, 'width' );
  515. widthInput.fieldView.on( 'input', () => {
  516. this.width = widthInput.fieldView.element.value;
  517. } );
  518. // -- Operator ---------------------------------------------------
  519. const operatorLabel = new View( locale );
  520. operatorLabel.setTemplate( {
  521. tag: 'span',
  522. attributes: {
  523. class: [
  524. 'ck-table-form__dimension-operator'
  525. ]
  526. },
  527. children: [
  528. { text: '×' }
  529. ]
  530. } );
  531. // -- Height ---------------------------------------------------
  532. const heightInput = new LabeledFieldView( locale, createLabeledInputText );
  533. heightInput.set( {
  534. label: t( 'Height' ),
  535. class: 'ck-table-form__dimensions-row__height'
  536. } );
  537. heightInput.fieldView.bind( 'value' ).to( this, 'height' );
  538. heightInput.fieldView.on( 'input', () => {
  539. this.height = heightInput.fieldView.element.value;
  540. } );
  541. return {
  542. dimensionsLabel,
  543. widthInput,
  544. operatorLabel,
  545. heightInput
  546. };
  547. }
  548. /**
  549. * Creates the following form fields:
  550. *
  551. * * {@link #paddingInput}.
  552. *
  553. * @private
  554. * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}
  555. */
  556. _createPaddingField() {
  557. const locale = this.locale;
  558. const t = this.t;
  559. const paddingInput = new LabeledFieldView( locale, createLabeledInputText );
  560. paddingInput.set( {
  561. label: t( 'Padding' ),
  562. class: 'ck-table-cell-properties-form__padding'
  563. } );
  564. paddingInput.fieldView.bind( 'value' ).to( this, 'padding' );
  565. paddingInput.fieldView.on( 'input', () => {
  566. this.padding = paddingInput.fieldView.element.value;
  567. } );
  568. return paddingInput;
  569. }
  570. /**
  571. * Creates the following form fields:
  572. *
  573. * * {@link #horizontalAlignmentToolbar},
  574. * * {@link #verticalAlignmentToolbar}.
  575. *
  576. * @private
  577. * @returns {Object.<String,module:ui/view~View>}
  578. */
  579. _createAlignmentFields() {
  580. const locale = this.locale;
  581. const t = this.t;
  582. const alignmentLabel = new LabelView( locale );
  583. alignmentLabel.text = t( 'Table cell text alignment' );
  584. // -- Horizontal ---------------------------------------------------
  585. const horizontalAlignmentToolbar = new ToolbarView( locale );
  586. const isContentRTL = this.locale.contentLanguageDirection === 'rtl';
  587. horizontalAlignmentToolbar.set( {
  588. isCompact: true,
  589. ariaLabel: t( 'Horizontal text alignment toolbar' )
  590. } );
  591. fillToolbar( {
  592. view: this,
  593. icons: ALIGNMENT_ICONS,
  594. toolbar: horizontalAlignmentToolbar,
  595. labels: this._horizontalAlignmentLabels,
  596. propertyName: 'horizontalAlignment',
  597. nameToValue: name => {
  598. return name === ( isContentRTL ? 'right' : 'left' ) ? '' : name;
  599. }
  600. } );
  601. // -- Vertical -----------------------------------------------------
  602. const verticalAlignmentToolbar = new ToolbarView( locale );
  603. verticalAlignmentToolbar.set( {
  604. isCompact: true,
  605. ariaLabel: t( 'Vertical text alignment toolbar' )
  606. } );
  607. fillToolbar( {
  608. view: this,
  609. icons: ALIGNMENT_ICONS,
  610. toolbar: verticalAlignmentToolbar,
  611. labels: this._verticalAlignmentLabels,
  612. propertyName: 'verticalAlignment',
  613. nameToValue: name => {
  614. return name === 'middle' ? '' : name;
  615. }
  616. } );
  617. return {
  618. horizontalAlignmentToolbar,
  619. verticalAlignmentToolbar,
  620. alignmentLabel
  621. };
  622. }
  623. /**
  624. * Creates the following form controls:
  625. *
  626. * * {@link #saveButtonView},
  627. * * {@link #cancelButtonView}.
  628. *
  629. * @private
  630. * @returns {Object.<String,module:ui/view~View>}
  631. */
  632. _createActionButtons() {
  633. const locale = this.locale;
  634. const t = this.t;
  635. const saveButtonView = new ButtonView( locale );
  636. const cancelButtonView = new ButtonView( locale );
  637. const fieldsThatShouldValidateToSave = [
  638. this.borderWidthInput,
  639. this.borderColorInput,
  640. this.backgroundInput,
  641. this.paddingInput
  642. ];
  643. saveButtonView.set( {
  644. label: t( 'Save' ),
  645. icon: checkIcon,
  646. class: 'ck-button-save',
  647. type: 'submit',
  648. withText: true
  649. } );
  650. saveButtonView.bind( 'isEnabled' ).toMany( fieldsThatShouldValidateToSave, 'errorText', ( ...errorTexts ) => {
  651. return errorTexts.every( errorText => !errorText );
  652. } );
  653. cancelButtonView.set( {
  654. label: t( 'Cancel' ),
  655. icon: cancelIcon,
  656. class: 'ck-button-cancel',
  657. type: 'cancel',
  658. withText: true
  659. } );
  660. cancelButtonView.delegate( 'execute' ).to( this, 'cancel' );
  661. return {
  662. saveButtonView, cancelButtonView
  663. };
  664. }
  665. /**
  666. * Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.
  667. *
  668. * @private
  669. * @type {Object.<String,String>}
  670. */
  671. get _horizontalAlignmentLabels() {
  672. const locale = this.locale;
  673. const t = this.t;
  674. const left = t( 'Align cell text to the left' );
  675. const center = t( 'Align cell text to the center' );
  676. const right = t( 'Align cell text to the right' );
  677. const justify = t( 'Justify cell text' );
  678. // Returns object with a proper order of labels.
  679. if ( locale.uiLanguageDirection === 'rtl' ) {
  680. return { right, center, left, justify };
  681. } else {
  682. return { left, center, right, justify };
  683. }
  684. }
  685. /**
  686. * Provides localized labels for {@link #verticalAlignmentToolbar} buttons.
  687. *
  688. * @private
  689. * @type {Object.<String,String>}
  690. */
  691. get _verticalAlignmentLabels() {
  692. const t = this.t;
  693. return {
  694. top: t( 'Align cell text to the top' ),
  695. middle: t( 'Align cell text to the middle' ),
  696. bottom: t( 'Align cell text to the bottom' )
  697. };
  698. }
  699. }
  700. function isBorderStyleSet( value ) {
  701. return !!value;
  702. }