plugin.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /**
  2. * Combined slider controls for adjusting line-height and letter-spacing values.
  3. *
  4. * @license Copyright (c) 2018, Green Cat Software - Xavier Cho. All rights reserved.
  5. *
  6. * The addon is distributed under the same license terms as the original addon
  7. * which can be found here: https://ckeditor.com/cke4/addon/spacingsliders
  8. */
  9. CKEDITOR.plugins.add( 'spacingsliders', {
  10. requires: 'panelbutton,floatpanel',
  11. lang: 'en,ko,uk', // %REMOVE_LINE_CORE%
  12. icons: 'spacingsliders', // %REMOVE_LINE_CORE%
  13. hidpi: false, // %REMOVE_LINE_CORE%
  14. init: function( editor ) {
  15. var config = editor.config,
  16. lang = editor.lang.spacingsliders;
  17. var cssPath = this.path + 'skins/default.css';
  18. var getConfig = function( value, defaultValue) {
  19. return value === undefined ? defaultValue : value;
  20. };
  21. var controls = {
  22. lineheight: new CKEDITOR.spacingControl(
  23. {
  24. name: 'lineheight',
  25. min: getConfig( CKEDITOR.config.lineheight_min, 0 ),
  26. max: getConfig( CKEDITOR.config.lineheight_max, 3 ),
  27. step: getConfig( CKEDITOR.config.lineheight_step, 0.1 )
  28. },
  29. editor ),
  30. letterspacing: new CKEDITOR.spacingControl(
  31. {
  32. name: 'letterspacing',
  33. min: getConfig( CKEDITOR.config.letterspacing_min, -20 ),
  34. max: getConfig( CKEDITOR.config.letterspacing_max, 20 )
  35. },
  36. editor )
  37. };
  38. var styles = [];
  39. for ( name in controls ) {
  40. var control = controls[name];
  41. styles.push( control.createStyle() );
  42. }
  43. editor.ui.add( 'spacingsliders', CKEDITOR.UI_PANELBUTTON, {
  44. label: lang.title,
  45. title: lang.title,
  46. modes: {
  47. wysiwyg: 1
  48. },
  49. editorFocus: 0,
  50. toolbar: 'styles,' + 40,
  51. allowedContent: styles,
  52. panel: {
  53. css: CKEDITOR.skin.getPath( 'editor' ),
  54. attributes: {
  55. role: 'listbox',
  56. 'aria-label': lang.panelTitle
  57. }
  58. },
  59. onBlock: function( panel, block ) {
  60. var document = block.element.getDocument();
  61. document.appendStyleSheet( cssPath );
  62. document.getBody().setStyle( 'overflow', 'hidden' );
  63. block.autoSize = true;
  64. block.element.addClass( 'cke_spacingblock' );
  65. for ( var id in controls ) {
  66. controls[id].render( block.element );
  67. }
  68. },
  69. onOpen: function() {
  70. var selection = editor.getSelection(),
  71. block = selection && selection.getStartElement(),
  72. path = editor.elementPath( block );
  73. for ( var id in controls ) {
  74. controls[id].update( path, block );
  75. }
  76. }
  77. });
  78. }
  79. } );
  80. CKEDITOR.spacingControl = CKEDITOR.tools.createClass({
  81. $: function( settings, editor ) {
  82. this.settings = settings;
  83. this.editor = editor;
  84. this.definition = editor.config[ 'spacingsliders_' + settings.name + 'Style' ];
  85. },
  86. proto: {
  87. createStyle: function( size ) {
  88. var args = size ? { size: size } : undefined;
  89. return new CKEDITOR.style( this.definition, args );
  90. },
  91. getValue: function() {
  92. if ( !this.element ) return;
  93. return this.input.$.value;
  94. },
  95. setValue: function( value ) {
  96. if ( !this.element ) return;
  97. this.input.$.value = value;
  98. this.label.setHtml( value );
  99. var style = this.createStyle( value );
  100. var path = this.editor.elementPath();
  101. if ( path && style.checkApplicable( path, this.editor ) ) {
  102. var selection = this.editor.getSelection();
  103. var locked = selection.isLocked;
  104. if ( locked ) {
  105. selection.unlock();
  106. }
  107. this.editor.removeStyle( new CKEDITOR.style( this.definition, { size: 'inherit' } ) );
  108. if ( value ) {
  109. this.editor.applyStyle( style );
  110. }
  111. if ( locked ) {
  112. selection.lock();
  113. }
  114. }
  115. },
  116. isEnabled: function () {
  117. return this.element && this.input.$.disabled !== true;
  118. },
  119. setEnabled: function ( value ) {
  120. if ( !this.element ) return;
  121. this.input.$.disabled = !value;
  122. if ( value ) {
  123. this.element.removeClass( 'disabled' );
  124. } else {
  125. this.element.addClass( 'disabled' );
  126. this.label.setHtml( '-' );
  127. this.input.value = 0;
  128. }
  129. },
  130. render: function( parent ) {
  131. var onChange = CKEDITOR.tools.addFunction( function ( value, saveSnapshot ) {
  132. this.setValue( value );
  133. if ( saveSnapshot ) {
  134. this.editor.fire( 'saveSnapshot' );
  135. }
  136. }, this );
  137. var lang = this.editor.lang.spacingsliders;
  138. var output = [];
  139. var value = 0;
  140. output.push( '<div id="' );
  141. output.push( this.settings.name );
  142. output.push( '" class="cke_spacingcontrol" title="">' );
  143. output.push( '<label>' );
  144. output.push( lang.labels[ this.settings.name ] );
  145. output.push( '</label>' );
  146. output.push( '<input type="range" ');
  147. output.push( ' oninput="CKEDITOR.tools.callFunction( ' );
  148. output.push( onChange );
  149. output.push( ', this.value );" ' );
  150. output.push( ' onchange="CKEDITOR.tools.callFunction( ' );
  151. output.push( onChange );
  152. output.push( ', this.value, true );" ' );
  153. output.push( 'step="' );
  154. output.push( this.settings.step || 1 );
  155. output.push( '" ' );
  156. output.push( 'min="' );
  157. output.push( this.settings.min || 0 );
  158. output.push( '" ' );
  159. output.push( 'max="' );
  160. output.push( this.settings.max || 100 );
  161. output.push( '" />' );
  162. output.push( '<span>' );
  163. output.push( value );
  164. output.push( '</span>' );
  165. output.push( '</div>' );
  166. parent.appendHtml( output.join( '' ) );
  167. this.element = parent.findOne( '#' + this.settings.name );
  168. this.input = parent.findOne( '#' + this.settings.name + ' input' );
  169. this.label = parent.findOne( '#' + this.settings.name + ' span' );
  170. },
  171. update: function( path, block ) {
  172. var value = path ? this.definition.getStyleValue( path, block ) : undefined;
  173. if ( parseFloat( value ) === value ) {
  174. var rounded = Math.round( value * 10 ) / 10;
  175. this.setEnabled( true );
  176. this.input.$.value = rounded;
  177. this.label.setHtml( rounded);
  178. } else {
  179. this.setEnabled( false );
  180. }
  181. }
  182. }
  183. });
  184. /**
  185. * @cfg [spacingsliders_lineheightStyle=see source]
  186. * @member CKEDITOR.config
  187. */
  188. CKEDITOR.config.spacingsliders_lineheightStyle = {
  189. type: CKEDITOR.STYLE_BLOCK,
  190. element: 'div',
  191. styles: { 'line-height': '#(size)' },
  192. getStyleValue: function( path, block ) {
  193. var convert = CKEDITOR.tools.convertToPx;
  194. var size = convert( block.getComputedStyle( 'font-size' ) );
  195. var value = convert( block.getComputedStyle( 'line-height' ) );
  196. return size ? value / size : 0;
  197. }
  198. };
  199. /**
  200. * @cfg [spacingsliders_letterspacingStyle=see source]
  201. * @member CKEDITOR.config
  202. */
  203. CKEDITOR.config.spacingsliders_letterspacingStyle = {
  204. element: 'div',
  205. styles: { 'letter-spacing': '#(size)px' },
  206. getStyleValue: function( path, block ) {
  207. var elem = path.lastElement;
  208. var value = elem.getComputedStyle( 'letter-spacing' );
  209. if ( !/^[-]?[0-9\\.]+([a-z]*)$/.test( value ) ) {
  210. return 0;
  211. }
  212. if ( value.startsWith( '-' )) {
  213. // CKEDITOR.tools.convertToPx can't calculate a negative value.
  214. return CKEDITOR.tools.convertToPx( value.substring( 1 ) ) * -1;
  215. } else {
  216. return CKEDITOR.tools.convertToPx( value );
  217. }
  218. }
  219. };
  220. /**
  221. * Minimum value for line height.
  222. * @cfg {Number} [lineheight_min=0]
  223. * @member CKEDITOR.config
  224. */
  225. /**
  226. * Maximum value for line height.
  227. * @cfg {Number} [lineheight_max=4]
  228. * @member CKEDITOR.config
  229. */
  230. /**
  231. * Interval (step) to be used for line height control.
  232. * @cfg {Number} [lineheight_step=0.1]
  233. * @member CKEDITOR.config
  234. */
  235. /**
  236. * Minimum value for letter spacing.
  237. * @cfg {Number} [letterspacing_min=-20]
  238. * @member CKEDITOR.config
  239. */
  240. /**
  241. * Maximum value for letter spacing.
  242. * @cfg {Number} [letterspacing_max=20]
  243. * @member CKEDITOR.config
  244. */