Permalink
Browse files

feature(ckeditor): added editor autogrow plugin

  • Loading branch information...
jdalsem committed Apr 15, 2016
1 parent f43a656 commit 771abac8a2130a83629fa3be8ba16161c36fc4fa
@@ -0,0 +1,209 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview The Auto Grow plugin.
+ */
+
+'use strict';
+
+( function() {
+ CKEDITOR.plugins.add( 'autogrow', {
+ init: function( editor ) {
+ // This feature is available only for themed ui instance.
+ if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE )
+ return;
+
+ editor.on( 'instanceReady', function() {
+ // Simply set auto height with div wysiwyg.
+ if ( editor.editable().isInline() )
+ editor.ui.space( 'contents' ).setStyle( 'height', 'auto' );
+ // For classic (`iframe`-based) wysiwyg we need to resize the editor.
+ else
+ initIframeAutogrow( editor );
+ } );
+ }
+ } );
+
+ function initIframeAutogrow( editor ) {
+ var lastHeight,
+ doc,
+ markerContainer,
+ scrollable,
+ marker,
+ configBottomSpace = editor.config.autoGrow_bottomSpace || 0,
+ configMinHeight = editor.config.autoGrow_minHeight !== undefined ? editor.config.autoGrow_minHeight : 200,
+ configMaxHeight = editor.config.autoGrow_maxHeight || Infinity,
+ maxHeightIsUnlimited = !editor.config.autoGrow_maxHeight;
+
+ editor.addCommand( 'autogrow', {
+ exec: resizeEditor,
+ modes: { wysiwyg: 1 },
+ readOnly: 1,
+ canUndo: false,
+ editorFocus: false
+ } );
+
+ var eventsList = { contentDom: 1, key: 1, selectionChange: 1, insertElement: 1, mode: 1 };
+ for ( var eventName in eventsList ) {
+ editor.on( eventName, function( evt ) {
+ // Some time is required for insertHtml, and it gives other events better performance as well.
+ if ( evt.editor.mode == 'wysiwyg' ) {
+ setTimeout( function() {
+ if ( isNotResizable() ) {
+ lastHeight = null;
+ return;
+ }
+
+ resizeEditor();
+
+ // Second pass to make correction upon the first resize, e.g. scrollbar.
+ // If height is unlimited vertical scrollbar was removed in the first
+ // resizeEditor() call, so we don't need the second pass.
+ if ( !maxHeightIsUnlimited )
+ resizeEditor();
+ }, 100 );
+ }
+ } );
+ }
+
+ // Coordinate with the "maximize" plugin. (#9311)
+ editor.on( 'afterCommandExec', function( evt ) {
+ if ( evt.data.name == 'maximize' && evt.editor.mode == 'wysiwyg' ) {
+ if ( evt.data.command.state == CKEDITOR.TRISTATE_ON )
+ scrollable.removeStyle( 'overflow-y' );
+ else
+ resizeEditor();
+ }
+ } );
+
+ editor.on( 'contentDom', refreshCache );
+
+ refreshCache();
+ editor.config.autoGrow_onStartup && editor.execCommand( 'autogrow' );
+
+ function refreshCache() {
+ doc = editor.document;
+ markerContainer = doc[ CKEDITOR.env.ie ? 'getBody' : 'getDocumentElement' ]();
+
+ // Quirks mode overflows body, standards overflows document element.
+ scrollable = CKEDITOR.env.quirks ? doc.getBody() : doc.getDocumentElement();
+
+ marker = CKEDITOR.dom.element.createFromHtml(
+ '<span style="margin:0;padding:0;border:0;clear:both;width:1px;height:1px;display:block;">' +
+ ( CKEDITOR.env.webkit ? '&nbsp;' : '' ) +
+ '</span>',
+ doc );
+ }
+
+ function isNotResizable() {
+ var maximizeCommand = editor.getCommand( 'maximize' );
+
+ return (
+ !editor.window ||
+ // Disable autogrow when the editor is maximized. (#6339)
+ maximizeCommand && maximizeCommand.state == CKEDITOR.TRISTATE_ON
+ );
+ }
+
+ // Actual content height, figured out by appending check the last element's document position.
+ function contentHeight() {
+ // Append a temporary marker element.
+ markerContainer.append( marker );
+ var height = marker.getDocumentPosition( doc ).y + marker.$.offsetHeight;
+ marker.remove();
+
+ return height;
+ }
+
+ function resizeEditor() {
+ // Hide scroll because we won't need it at all.
+ // Thanks to that we'll need only one resizeEditor() call per change.
+ if ( maxHeightIsUnlimited )
+ scrollable.setStyle( 'overflow-y', 'hidden' );
+
+ var currentHeight = editor.window.getViewPaneSize().height,
+ newHeight = contentHeight();
+
+ // Additional space specified by user.
+ newHeight += configBottomSpace;
+ newHeight = Math.max( newHeight, configMinHeight );
+ newHeight = Math.min( newHeight, configMaxHeight );
+
+ // #10196 Do not resize editor if new height is equal
+ // to the one set by previous resizeEditor() call.
+ if ( newHeight != currentHeight && lastHeight != newHeight ) {
+ newHeight = editor.fire( 'autoGrow', { currentHeight: currentHeight, newHeight: newHeight } ).newHeight;
+ editor.resize( editor.container.getStyle( 'width' ), newHeight, true );
+ lastHeight = newHeight;
+ }
+
+ if ( !maxHeightIsUnlimited ) {
+ if ( newHeight < configMaxHeight && scrollable.$.scrollHeight > scrollable.$.clientHeight )
+ scrollable.setStyle( 'overflow-y', 'hidden' );
+ else
+ scrollable.removeStyle( 'overflow-y' );
+ }
+ }
+ }
+} )();
+
+/**
+ * The minimum height that the editor can assume when adjusting to content by using the Auto Grow
+ * feature. This option accepts a value in pixels, without the unit (for example: `300`).
+ *
+ * config.autoGrow_minHeight = 300;
+ *
+ * @since 3.4
+ * @cfg {Number} [autoGrow_minHeight=200]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * The maximum height that the editor can assume when adjusting to content by using the Auto Grow
+ * feature. This option accepts a value in pixels, without the unit (for example: `600`).
+ * Zero (`0`) means that the maximum height is not limited and the editor will expand infinitely.
+ *
+ * config.autoGrow_maxHeight = 400;
+ *
+ * @since 3.4
+ * @cfg {Number} [autoGrow_maxHeight=0]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * Whether automatic editor height adjustment brought by the Auto Grow feature should happen on
+ * editor creation.
+ *
+ * config.autoGrow_onStartup = true;
+ *
+ * @since 3.6.2
+ * @cfg {Boolean} [autoGrow_onStartup=false]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * Extra vertical space to be added between the content and the editor bottom bar when adjusting
+ * editor height to content by using the Auto Grow feature. This option accepts a value in pixels,
+ * without the unit (for example: `50`).
+ *
+ * config.autoGrow_bottomSpace = 50;
+ *
+ * @since 3.6.2
+ * @cfg {Number} [autoGrow_bottomSpace=0]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * Fired when the Auto Grow plugin is about to change the size of the editor.
+ *
+ * @event autogrow
+ * @member CKEDITOR.editor
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param data
+ * @param {Number} data.currentHeight The current editor height (before resizing).
+ * @param {Number} data.newHeight The new editor height (after resizing). It can be changed
+ * to achieve a different height value to be used instead.
+ */
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>AutoGrow Plugin &mdash; CKEditor Sample</title>
+ <script src="../../../ckeditor.js"></script>
+ <link rel="stylesheet" href="../../../samples/sample.css">
+ <meta name="ckeditor-sample-name" content="AutoGrow plugin">
+ <meta name="ckeditor-sample-group" content="Plugins">
+ <meta name="ckeditor-sample-description" content="Using the AutoGrow plugin in order to make the editor grow to fit the size of its content.">
+</head>
+<body>
+ <h1 class="samples">
+ <a href="../../../samples/index.html">CKEditor Samples</a> &raquo; Using AutoGrow Plugin
+ </h1>
+ <div class="description">
+ <p>
+ This sample shows how to configure CKEditor instances to use the
+ <strong>AutoGrow</strong> (<code>autogrow</code>) plugin that lets the editor window expand
+ and shrink depending on the amount and size of content entered in the editing area.
+ </p>
+ <p>
+ In its default implementation the <strong>AutoGrow feature</strong> can expand the
+ CKEditor window infinitely in order to avoid introducing scrollbars to the editing area.
+ </p>
+ <p>
+ It is also possible to set a maximum height for the editor window. Once CKEditor
+ editing area reaches the value in pixels specified in the
+ <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-autoGrow_maxHeight">autoGrow_maxHeight</a></code>
+ configuration setting, scrollbars will be added and the editor window will no longer expand.
+ </p>
+ <p>
+ To add a CKEditor instance using the <code>autogrow</code> plugin and its
+ <code>autoGrow_maxHeight</code> attribute, insert the following JavaScript call to your code:
+ </p>
+<pre class="samples">
+CKEDITOR.replace( '<em>textarea_id</em>', {
+ <strong>extraPlugins: 'autogrow',</strong>
+ autoGrow_maxHeight: 800,
+
+ // Remove the Resize plugin as it does not make sense to use it in conjunction with the AutoGrow plugin.
+ removePlugins: 'resize'
+});</pre>
+ <p>
+ Note that <code><em>textarea_id</em></code> in the code above is the <code>id</code> attribute of
+ the <code>&lt;textarea&gt;</code> element to be replaced with CKEditor. The maximum height should
+ be given in pixels.
+ </p>
+ </div>
+ <form action="../../../samples/sample_posteddata.php" method="post">
+ <p>
+ <label for="editor1">
+ CKEditor using the <code>autogrow</code> plugin with its default configuration:
+ </label>
+ <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>
+ <script>
+
+ CKEDITOR.replace( 'editor1', {
+ extraPlugins: 'autogrow',
+ removePlugins: 'resize'
+ });
+
+ </script>
+ </p>
+ <p>
+ <label for="editor2">
+ CKEditor using the <code>autogrow</code> plugin with maximum height set to 400 pixels:
+ </label>
+ <textarea cols="80" id="editor2" name="editor2" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>
+ <script>
+
+ CKEDITOR.replace( 'editor2', {
+ extraPlugins: 'autogrow',
+ autoGrow_maxHeight: 400,
+ removePlugins: 'resize'
+ });
+
+ </script>
+ </p>
+ <p>
+ <input type="submit" value="Submit">
+ </p>
+ </form>
+ <div id="footer">
+ <hr>
+ <p>
+ CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+ </p>
+ <p id="copy">
+ Copyright &copy; 2003-2015, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+ Knabben. All rights reserved.
+ </p>
+ </div>
+</body>
+</html>
@@ -9,7 +9,7 @@ define(function(require) {
allowedContent: true,
baseHref: elgg.get_site_url(),
removePlugins: 'liststyle,contextmenu,tabletools',
- extraPlugins: 'blockimagepaste',
+ extraPlugins: 'blockimagepaste,autogrow',
defaultLanguage: 'en',
language: elgg.get_language(),
skin: 'moono',

0 comments on commit 771abac

Please sign in to comment.