plugin.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or http://ckeditor.com/license
  4. */
  5. /**
  6. * @fileOverview The Source Editing Area plugin. It registers the "source" editing
  7. * mode, which displays raw HTML data being edited in the editor.
  8. */
  9. ( function() {
  10. CKEDITOR.plugins.add( 'sourcearea', {
  11. // jscs:disable maximumLineLength
  12. lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%
  13. // jscs:enable maximumLineLength
  14. icons: 'source,source-rtl', // %REMOVE_LINE_CORE%
  15. hidpi: true, // %REMOVE_LINE_CORE%
  16. init: function( editor ) {
  17. // Source mode in inline editors is only available through the "sourcedialog" plugin.
  18. if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE )
  19. return;
  20. var sourcearea = CKEDITOR.plugins.sourcearea;
  21. editor.addMode( 'source', function( callback ) {
  22. var contentsSpace = editor.ui.space( 'contents' ),
  23. textarea = contentsSpace.getDocument().createElement( 'textarea' );
  24. textarea.setStyles(
  25. CKEDITOR.tools.extend( {
  26. // IE7 has overflow the <textarea> from wrapping table cell.
  27. width: CKEDITOR.env.ie7Compat ? '99%' : '100%',
  28. height: '100%',
  29. resize: 'none',
  30. outline: 'none',
  31. 'text-align': 'left'
  32. },
  33. CKEDITOR.tools.cssVendorPrefix( 'tab-size', editor.config.sourceAreaTabSize || 4 ) ) );
  34. // Make sure that source code is always displayed LTR,
  35. // regardless of editor language (#10105).
  36. textarea.setAttribute( 'dir', 'ltr' );
  37. textarea.addClass( 'cke_source' ).addClass( 'cke_reset' ).addClass( 'cke_enable_context_menu' );
  38. editor.ui.space( 'contents' ).append( textarea );
  39. var editable = editor.editable( new sourceEditable( editor, textarea ) );
  40. // Fill the textarea with the current editor data.
  41. editable.setData( editor.getData( 1 ) );
  42. // Having to make <textarea> fixed sized to conquer the following bugs:
  43. // 1. The textarea height/width='100%' doesn't constraint to the 'td' in IE6/7.
  44. // 2. Unexpected vertical-scrolling behavior happens whenever focus is moving out of editor
  45. // if text content within it has overflowed. (#4762)
  46. if ( CKEDITOR.env.ie ) {
  47. editable.attachListener( editor, 'resize', onResize, editable );
  48. editable.attachListener( CKEDITOR.document.getWindow(), 'resize', onResize, editable );
  49. CKEDITOR.tools.setTimeout( onResize, 0, editable );
  50. }
  51. editor.fire( 'ariaWidget', this );
  52. callback();
  53. } );
  54. editor.addCommand( 'source', sourcearea.commands.source );
  55. if ( editor.ui.addButton ) {
  56. editor.ui.addButton( 'Source', {
  57. label: editor.lang.sourcearea.toolbar,
  58. command: 'source',
  59. toolbar: 'mode,10'
  60. } );
  61. }
  62. editor.on( 'mode', function() {
  63. editor.getCommand( 'source' ).setState( editor.mode == 'source' ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );
  64. } );
  65. var needsFocusHack = CKEDITOR.env.ie && CKEDITOR.env.version == 9;
  66. function onResize() {
  67. // We have to do something with focus on IE9, because if sourcearea had focus
  68. // before being resized, the caret ends somewhere in the editor UI (#11839).
  69. var wasActive = needsFocusHack && this.equals( CKEDITOR.document.getActive() );
  70. // Holder rectange size is stretched by textarea,
  71. // so hide it just for a moment.
  72. this.hide();
  73. this.setStyle( 'height', this.getParent().$.clientHeight + 'px' );
  74. this.setStyle( 'width', this.getParent().$.clientWidth + 'px' );
  75. // When we have proper holder size, show textarea again.
  76. this.show();
  77. if ( wasActive )
  78. this.focus();
  79. }
  80. }
  81. } );
  82. var sourceEditable = CKEDITOR.tools.createClass( {
  83. base: CKEDITOR.editable,
  84. proto: {
  85. setData: function( data ) {
  86. this.setValue( data );
  87. this.status = 'ready';
  88. this.editor.fire( 'dataReady' );
  89. },
  90. getData: function() {
  91. return this.getValue();
  92. },
  93. // Insertions are not supported in source editable.
  94. insertHtml: function() {},
  95. insertElement: function() {},
  96. insertText: function() {},
  97. // Read-only support for textarea.
  98. setReadOnly: function( isReadOnly ) {
  99. this[ ( isReadOnly ? 'set' : 'remove' ) + 'Attribute' ]( 'readOnly', 'readonly' );
  100. },
  101. detach: function() {
  102. sourceEditable.baseProto.detach.call( this );
  103. this.clearCustomData();
  104. this.remove();
  105. }
  106. }
  107. } );
  108. } )();
  109. CKEDITOR.plugins.sourcearea = {
  110. commands: {
  111. source: {
  112. modes: { wysiwyg: 1, source: 1 },
  113. editorFocus: false,
  114. readOnly: 1,
  115. exec: function( editor ) {
  116. if ( editor.mode == 'wysiwyg' )
  117. editor.fire( 'saveSnapshot' );
  118. editor.getCommand( 'source' ).setState( CKEDITOR.TRISTATE_DISABLED );
  119. editor.setMode( editor.mode == 'source' ? 'wysiwyg' : 'source' );
  120. },
  121. canUndo: false
  122. }
  123. }
  124. };
  125. /**
  126. * Controls the `tab-size` CSS property of the source editing area. Use it to set the width
  127. * of the tab character in the source view. Enter an integer to denote the number of spaces
  128. * that the tab will contain.
  129. *
  130. * **Note:** Works only with {@link #dataIndentationChars}
  131. * set to `'\t'`. Please consider that not all browsers support the `tab-size` CSS
  132. * property yet.
  133. *
  134. * // Set tab-size to 10 characters.
  135. * config.sourceAreaTabSize = 10;
  136. *
  137. * @cfg {Number} [sourceAreaTabSize=4]
  138. * @member CKEDITOR.config
  139. * @see CKEDITOR.config#dataIndentationChars
  140. */