textalternativeformview.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /**
  2. * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module image/imagetextalternative/ui/textalternativeformview
  7. */
  8. import View from '@ckeditor/ckeditor5-ui/src/view';
  9. import ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection';
  10. import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
  11. import LabeledInputView from '@ckeditor/ckeditor5-ui/src/labeledinput/labeledinputview';
  12. import InputTextView from '@ckeditor/ckeditor5-ui/src/inputtext/inputtextview';
  13. import submitHandler from '@ckeditor/ckeditor5-ui/src/bindings/submithandler';
  14. import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
  15. import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
  16. import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';
  17. import '../../../theme/textalternativeform.css';
  18. /**
  19. * The TextAlternativeFormView class.
  20. *
  21. * @extends module:ui/view~View
  22. */
  23. export default class TextAlternativeFormView extends View {
  24. /**
  25. * @inheritDoc
  26. */
  27. constructor( locale ) {
  28. super( locale );
  29. const t = this.locale.t;
  30. /**
  31. * Tracks information about DOM focus in the form.
  32. *
  33. * @readonly
  34. * @member {module:utils/focustracker~FocusTracker}
  35. */
  36. this.focusTracker = new FocusTracker();
  37. /**
  38. * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
  39. *
  40. * @readonly
  41. * @member {module:utils/keystrokehandler~KeystrokeHandler}
  42. */
  43. this.keystrokes = new KeystrokeHandler();
  44. /**
  45. * A textarea with a label.
  46. *
  47. * @member {module:ui/labeledinput/labeledinputview~LabeledInputView} #labeledTextarea
  48. */
  49. this.labeledInput = this._createLabeledInputView();
  50. /**
  51. * A button used to submit the form.
  52. *
  53. * @member {module:ui/button/buttonview~ButtonView} #saveButtonView
  54. */
  55. this.saveButtonView = this._createButton( t( 'Save' ) );
  56. this.saveButtonView.type = 'submit';
  57. /**
  58. * A button used to cancel the form.
  59. *
  60. * @member {module:ui/button/buttonview~ButtonView} #cancelButtonView
  61. */
  62. this.cancelButtonView = this._createButton( t( 'Cancel' ), 'cancel' );
  63. /**
  64. * A collection of views which can be focused in the form.
  65. *
  66. * @readonly
  67. * @protected
  68. * @member {module:ui/viewcollection~ViewCollection}
  69. */
  70. this._focusables = new ViewCollection();
  71. /**
  72. * Helps cycling over {@link #_focusables} in the form.
  73. *
  74. * @readonly
  75. * @protected
  76. * @member {module:ui/focuscycler~FocusCycler}
  77. */
  78. this._focusCycler = new FocusCycler( {
  79. focusables: this._focusables,
  80. focusTracker: this.focusTracker,
  81. keystrokeHandler: this.keystrokes,
  82. actions: {
  83. // Navigate form fields backwards using the Shift + Tab keystroke.
  84. focusPrevious: 'shift + tab',
  85. // Navigate form fields forwards using the Tab key.
  86. focusNext: 'tab'
  87. }
  88. } );
  89. this.saveButtonView.extendTemplate( {
  90. attributes: {
  91. class: [
  92. 'ck-button-action'
  93. ]
  94. }
  95. } );
  96. this.setTemplate( {
  97. tag: 'form',
  98. attributes: {
  99. class: [
  100. 'cke-text-alternative-form',
  101. ],
  102. // https://github.com/ckeditor/ckeditor5-image/issues/40
  103. tabindex: '-1'
  104. },
  105. children: [
  106. this.labeledInput,
  107. {
  108. tag: 'div',
  109. attributes: {
  110. class: [
  111. 'cke-text-alternative-form__actions'
  112. ]
  113. },
  114. children: [
  115. this.saveButtonView,
  116. this.cancelButtonView
  117. ]
  118. }
  119. ]
  120. } );
  121. }
  122. /**
  123. * @inheritDoc
  124. */
  125. render() {
  126. super.render();
  127. this.keystrokes.listenTo( this.element );
  128. submitHandler( { view: this } );
  129. [ this.labeledInput, this.saveButtonView, this.cancelButtonView ]
  130. .forEach( v => {
  131. // Register the view as focusable.
  132. this._focusables.add( v );
  133. // Register the view in the focus tracker.
  134. this.focusTracker.add( v.element );
  135. } );
  136. }
  137. /**
  138. * Creates the button view.
  139. *
  140. * @private
  141. * @param {String} label The button label
  142. * @param {String} [eventName] The event name that the ButtonView#execute event will be delegated to.
  143. * @returns {module:ui/button/buttonview~ButtonView} The button view instance.
  144. */
  145. _createButton( label, eventName ) {
  146. const button = new ButtonView( this.locale );
  147. button.label = label;
  148. button.withText = true;
  149. if ( eventName ) {
  150. button.delegate( 'execute' ).to( this, eventName );
  151. }
  152. return button;
  153. }
  154. /**
  155. * Creates an input with a label.
  156. *
  157. * @private
  158. * @return {module:ui/labeledinput/labeledinputview~LabeledInputView}
  159. */
  160. _createLabeledInputView() {
  161. const t = this.locale.t;
  162. const labeledInput = new LabeledInputView( this.locale, InputTextView );
  163. labeledInput.label = t( 'Text alternative' );
  164. return labeledInput;
  165. }
  166. }