linkformview.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /**
  2. * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module link/ui/linkformview
  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 FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
  15. import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';
  16. import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
  17. import '../../theme/linkform.css';
  18. /**
  19. * The link form view controller class.
  20. *
  21. * See {@link module:link/ui/linkformview~LinkFormView}.
  22. *
  23. * @extends module:ui/view~View
  24. */
  25. export default class LinkFormView extends View {
  26. /**
  27. * @inheritDoc
  28. */
  29. constructor( locale ) {
  30. super( locale );
  31. const t = locale.t;
  32. /**
  33. * Tracks information about DOM focus in the form.
  34. *
  35. * @readonly
  36. * @member {module:utils/focustracker~FocusTracker}
  37. */
  38. this.focusTracker = new FocusTracker();
  39. /**
  40. * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
  41. *
  42. * @readonly
  43. * @member {module:utils/keystrokehandler~KeystrokeHandler}
  44. */
  45. this.keystrokes = new KeystrokeHandler();
  46. /**
  47. * The URL input view.
  48. *
  49. * @member {module:ui/labeledinput/labeledinputview~LabeledInputView}
  50. */
  51. this.urlInputView = this._createUrlInput();
  52. /**
  53. * The Save button view.
  54. *
  55. * @member {module:ui/button/buttonview~ButtonView}
  56. */
  57. this.saveButtonView = this._createButton( t( 'Save' ) );
  58. this.saveButtonView.type = 'submit';
  59. /**
  60. * The Cancel button view.
  61. *
  62. * @member {module:ui/button/buttonview~ButtonView}
  63. */
  64. this.cancelButtonView = this._createButton( t( 'Cancel' ), 'cancel' );
  65. /**
  66. * The Unlink button view.
  67. *
  68. * @member {module:ui/button/buttonview~ButtonView}
  69. */
  70. this.unlinkButtonView = this._createButton( t( 'Unlink' ), 'unlink' );
  71. /**
  72. * A collection of views which can be focused in the form.
  73. *
  74. * @readonly
  75. * @protected
  76. * @member {module:ui/viewcollection~ViewCollection}
  77. */
  78. this._focusables = new ViewCollection();
  79. /**
  80. * Helps cycling over {@link #_focusables} in the form.
  81. *
  82. * @readonly
  83. * @protected
  84. * @member {module:ui/focuscycler~FocusCycler}
  85. */
  86. this._focusCycler = new FocusCycler( {
  87. focusables: this._focusables,
  88. focusTracker: this.focusTracker,
  89. keystrokeHandler: this.keystrokes,
  90. actions: {
  91. // Navigate form fields backwards using the Shift + Tab keystroke.
  92. focusPrevious: 'shift + tab',
  93. // Navigate form fields forwards using the Tab key.
  94. focusNext: 'tab'
  95. }
  96. } );
  97. this.saveButtonView.extendTemplate( {
  98. attributes: {
  99. class: [
  100. 'ck-button-action'
  101. ]
  102. }
  103. } );
  104. this.setTemplate( {
  105. tag: 'form',
  106. attributes: {
  107. class: [
  108. 'ck-link-form',
  109. ],
  110. // https://github.com/ckeditor/ckeditor5-link/issues/90
  111. tabindex: '-1'
  112. },
  113. children: [
  114. this.urlInputView,
  115. {
  116. tag: 'div',
  117. attributes: {
  118. class: [
  119. 'ck-link-form__actions'
  120. ]
  121. },
  122. children: [
  123. this.saveButtonView,
  124. this.cancelButtonView,
  125. this.unlinkButtonView
  126. ]
  127. }
  128. ]
  129. } );
  130. }
  131. /**
  132. * @inheritDoc
  133. */
  134. render() {
  135. super.render();
  136. submitHandler( {
  137. view: this
  138. } );
  139. const childViews = [
  140. this.urlInputView,
  141. this.saveButtonView,
  142. this.cancelButtonView,
  143. this.unlinkButtonView
  144. ];
  145. childViews.forEach( v => {
  146. // Register the view as focusable.
  147. this._focusables.add( v );
  148. // Register the view in the focus tracker.
  149. this.focusTracker.add( v.element );
  150. } );
  151. // Start listening for the keystrokes coming from #element.
  152. this.keystrokes.listenTo( this.element );
  153. }
  154. /**
  155. * Focuses the fist {@link #_focusables} in the form.
  156. */
  157. focus() {
  158. this._focusCycler.focusFirst();
  159. }
  160. /**
  161. * Creates a labeled input view.
  162. *
  163. * @private
  164. * @returns {module:ui/labeledinput/labeledinputview~LabeledInputView} Labeled input view instance.
  165. */
  166. _createUrlInput() {
  167. const t = this.locale.t;
  168. const labeledInput = new LabeledInputView( this.locale, InputTextView );
  169. labeledInput.label = t( 'Link URL' );
  170. labeledInput.inputView.placeholder = 'https://example.com';
  171. return labeledInput;
  172. }
  173. /**
  174. * Creates a button view.
  175. *
  176. * @private
  177. * @param {String} label The button label
  178. * @param {String} [eventName] An event name that the `ButtonView#execute` event will be delegated to.
  179. * @returns {module:ui/button/buttonview~ButtonView} The button view instance.
  180. */
  181. _createButton( label, eventName ) {
  182. const button = new ButtonView( this.locale );
  183. button.label = label;
  184. button.withText = true;
  185. if ( eventName ) {
  186. button.delegate( 'execute' ).to( this, eventName );
  187. }
  188. return button;
  189. }
  190. }
  191. /**
  192. * Fired when the form view is submitted (when one of the children triggered the submit event),
  193. * e.g. click on {@link #saveButtonView}.
  194. *
  195. * @event submit
  196. */
  197. /**
  198. * Fired when the form view is canceled, e.g. click on {@link #cancelButtonView}.
  199. *
  200. * @event cancel
  201. */
  202. /**
  203. * Fired when the {@link #unlinkButtonView} is clicked.
  204. *
  205. * @event unlink
  206. */