codeblockui.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /**
  2. * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /**
  6. * @module code-block/codeblockui
  7. */
  8. import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
  9. import Collection from '@ckeditor/ckeditor5-utils/src/collection';
  10. import Model from '@ckeditor/ckeditor5-ui/src/model';
  11. import SplitButtonView from '@ckeditor/ckeditor5-ui/src/dropdown/button/splitbuttonview';
  12. import { createDropdown, addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils';
  13. import { getNormalizedAndLocalizedLanguageDefinitions } from './utils';
  14. import codeBlockIcon from '../theme/icons/codeblock.svg';
  15. import '../theme/codeblock.css';
  16. /**
  17. * The code block UI plugin.
  18. *
  19. * Introduces the `'codeBlock'` dropdown.
  20. *
  21. * @extends module:core/plugin~Plugin
  22. */
  23. export default class CodeBlockUI extends Plugin {
  24. /**
  25. * @inheritDoc
  26. */
  27. init() {
  28. const editor = this.editor;
  29. const t = editor.t;
  30. const componentFactory = editor.ui.componentFactory;
  31. const normalizedLanguageDefs = getNormalizedAndLocalizedLanguageDefinitions( editor );
  32. const defaultLanguageDefinition = normalizedLanguageDefs[ 0 ];
  33. componentFactory.add( 'codeBlock', locale => {
  34. const command = editor.commands.get( 'codeBlock' );
  35. const dropdownView = createDropdown( locale, SplitButtonView );
  36. const splitButtonView = dropdownView.buttonView;
  37. splitButtonView.set( {
  38. label: t( 'Insert code block' ),
  39. tooltip: true,
  40. icon: codeBlockIcon,
  41. isToggleable: true
  42. } );
  43. splitButtonView.bind( 'isOn' ).to( command, 'value', value => !!value );
  44. splitButtonView.on( 'execute', () => {
  45. editor.execute( 'codeBlock', {
  46. language: defaultLanguageDefinition.language,
  47. } );
  48. editor.editing.view.focus();
  49. } );
  50. dropdownView.on( 'execute', evt => {
  51. editor.execute( 'codeBlock', {
  52. language: evt.source._codeBlockLanguage,
  53. forceValue: true
  54. } );
  55. editor.editing.view.focus();
  56. } );
  57. dropdownView.class = 'ck-code-block-dropdown';
  58. dropdownView.bind( 'isEnabled' ).to( command );
  59. addListToDropdown( dropdownView, this._getLanguageListItemDefinitions( normalizedLanguageDefs ) );
  60. return dropdownView;
  61. } );
  62. }
  63. /**
  64. * A helper returning a collection of the `codeBlock` dropdown items representing languages
  65. * available for the user to choose from.
  66. *
  67. * @private
  68. * @param {Array.<module:code-block/codeblock~CodeBlockLanguageDefinition>} normalizedLanguageDefs
  69. * @returns {Iterable.<module:ui/dropdown/utils~ListDropdownItemDefinition>}
  70. */
  71. _getLanguageListItemDefinitions( normalizedLanguageDefs ) {
  72. const editor = this.editor;
  73. const command = editor.commands.get( 'codeBlock' );
  74. const itemDefinitions = new Collection();
  75. for ( const languageDef of normalizedLanguageDefs ) {
  76. const definition = {
  77. type: 'button',
  78. model: new Model( {
  79. _codeBlockLanguage: languageDef.language,
  80. label: languageDef.label,
  81. withText: true
  82. } )
  83. };
  84. definition.model.bind( 'isOn' ).to( command, 'value', value => {
  85. return value === definition.model._codeBlockLanguage;
  86. } );
  87. itemDefinitions.add( definition );
  88. }
  89. return itemDefinitions;
  90. }
  91. }