Skip to content
This repository

Autoresize the content area? #18

Open
wvl opened this Issue March 15, 2012 · 74 comments
Wayne Larsen
wvl commented March 15, 2012

Is there any way to auto resize the editing area based on the size of the content?

Christopher Blum
Collaborator
tiff commented March 15, 2012

Something like this could work (untested):

editor.observe("load", function() {
  editor.composer.element.addEventListener("keyup", function() {
    editor.composer.iframe.style.height = editor.composer.element.scrollHeight + "px";
  });
});

I'm considering it to implement it for wysihtml5 0.4.
Please don't use the issues for questions or support requests :) thanks!

Christopher Blum tiff closed this March 15, 2012
Wayne Larsen
wvl commented March 16, 2012

I would appreciate this feature. That code causes the height to grow, but not shrink.

With textareas, the accepted means of doing this seems to be to clone the textarea, set the clone's height to 0, then track the height of the original textarea's height to the scrollTop of the clone. One example is:
https://github.com/jackmoore/autosize/blob/master/jquery.autosize.js

However, assuming this approach works, it would require cloning the contenteditable in the iframe. I'm not sure that's too feasible from outside wysihtml5.

Sorry for opening an issue for a question -- if there's a better place for such questions (aside from reading the source and figuring it out myself), maybe mention it in the README? There's lots of good stuff hidden, undocumented in the source, I thought I might've missed it.

Thanks.

Christopher Blum tiff reopened this March 22, 2012
Christopher Blum
Collaborator
tiff commented March 22, 2012

I hope I can implement something for v0.4.

@wvl Well apparently you are right: opening an issue is probably the best way right now to get an answer and share knowledge :) Thanks

Michael Archibald

Would it be possible to get a wiki?

Christopher Blum
Collaborator
tiff commented March 28, 2012

Of course. Coming soon!

Pablo Villalba
micho commented March 29, 2012

I :+1: on issues for feature requests. This way you can group everybody asking about the same thing. Thanks to this ticket I was able to come up to speed, if I get it working I will share a pull request

Pablo Villalba
micho commented March 29, 2012

Here's a working snippet that allows a textarea to resize: https://gist.github.com/2243439

It grows and shrinks. It calculates the target size by creating a test container to measure dimensions.

this.editor = new wysihtml5.Editor("textarea");
this.editor.observe("load", function () {
  $(this.composer.iframe).autoResize();
});
Christopher Blum
Collaborator
tiff commented March 30, 2012

Awesome. Will do a code review and consider implementing it. Thanks @micho!

Pablo Villalba
micho commented March 30, 2012

My only worries are using jQuery for measuring and some Underscore.

Justin Cooper

This seems to work quite well. Already had the dependencies, so no issues there. Thanks!

iceton

A dynamically-sized editor (that behaves like a contenteditable element directly on the page) is the number one thing I need to figure out before I can use this. Glad to hear it's got your attention.

Pablo Villalba
micho commented April 11, 2012
iceton

Saw that, thanks micho! I'm not using Underscore, so I'm hoping for/messing around with a library-independent solution.

Pablo Villalba
micho commented April 11, 2012
Edward Smith

I've found that the code @micho posted has an issue when the editor's contents contain an image without explicit height attributes.

This is because the image is not loaded when the height of the test container is measured.

While this adds another dependency, I'm using this plugin: https://github.com/desandro/imagesloaded (which sets up an imagesLoaded event, even for dynamically added images), and have modified the adjustHeight function to:

a.prototype.adjustHeight = function () {
    var a, b, c, d, e, _this;
    _this = this;
    this.$testContainer.width(this.$source.width());
    e = this.$testContainer.html("X").height();
    this.$testContainer.html(this.sourceContents());
    this.$testContainer.imagesLoaded(function(){
        d = parseInt(_this.$el.data("rows") || _this.$el.attr("rows")) || false;
        c = d === 1 ? 1 : _this.resizeBy * e;
        a = d ? e * d + 1 : _this.originalHeight;
        b = _this.$testContainer.height() + c;
        if (_this.heightLimit && b > _this.heightLimit) {
            b = _this.heightLimit;
        }
        if (b < a) {
            b = a;
        }
        b = Math.round(b);
        return _this.$el.css("min-height", b);
    });
};

Edit: As I experiment with this change, it seems to have some issues... Ok, there can be an issue, I think, where we're getting overlapping "imagesLoaded" events. By increasing the _.throttle window from 5ms to 100ms seems to have suppressed the problem, at least on this computer (needs more testing), but is still quick enough that it feels fine.

    a.prototype.watchForChanges = function () {
      var a = this;
      this.$source.bind("keyup keydown paste change focus", _.throttle(function (evt) {
        return a.adjustHeight(evt);
      }, $.support.touch ? 300 : 100));
      this.$el.closest("form").bind("reset", function () {
        return a.resetHeight();
      });
    };
Edward Smith

I've run across other difficulties with this resize process that I'm going to have to, for expediency, go back to @tiff's first solution and forgo shrinking.

In our case, we have a lot of images and oembed-previewed objects.

Every time the contents gets copied to the test node for sizing, all these assets reload again. Some of the images are cached, but some others are not, and the oembeds are not cached either, and this is causing a LOT of network traffic.

Just wanted to bring this up for anybody else that might have a content load similar to ours.

Shrink-to-fit: The snippet by @tiff above works for me in Chrome more or less by adding the following:

remove "height", "padding-top", "padding-bottom" from BOX_FORMATTING -because this is causing the fixed height of the iframe
add "min-height" to BOX_FORMATTING (so we can see a composer line)

add textarea{min-height: 2em;} in the CSS (height of this line)

Would be great if someone could try this. I think that the composer is already shrink-to-fit (because of inline-block), and its height can be copied to its parent iframe if it is allowed to.

TomoGlavas

I got this working properly by observing keyup, focus and blur. Shrinking works only on blur, but thats acceptable for me.

var resizeIframe = function() {
    editor.composer.iframe.style.height = editor.composer.element.scrollHeight + "px";
}

editor.on("load", function() {
  editor.composer.element.addEventListener("keyup", resizeIframe, false)
  editor.composer.element.addEventListener("blur", resizeIframe, false)
  editor.composer.element.addEventListener("focus", resizeIframe, false)
})

Didnt mess with BOX_FORMATTING.

beep
beep commented June 13, 2012

@TomoGlavas: Great fix. Having a bit of a focus issue, though: clicking at a lower point in the document causes the page to jump to the top. Related?

TomoGlavas

Yea, I had some strange effects happening too. Temporarily, I use a different check for height, as iframe and composer height values seem to not allways reflect reality. No strange effects with this code:

var resizeIframe = function() {
if($(chunk).find(".wysihtml5-sandbox").height() != editor.composer.element.offsetHeight) {
$(chunk).find(".wysihtml5-sandbox").height(editor.composer.element.offsetHeight);
}
}

Peter Fern
pdf commented August 22, 2012

@TomoGlavas what does chunk refer to in that last snippet?

TomoGlavas

Sory bout that, its a proprietary element of my cms. Here its just a html element containing the editor.

Peter Fern
pdf commented August 22, 2012

@TomoGlavas if I use the code from your last comment I get a weird effect where the box increases in size minutely for every character typed...

TomoGlavas

It is tricky, yes. Try playing the css of the editor (css that is applied to the body inside the iframe), specifically - padding. It affects the height calculation and can cause such effects.

edslocomb edslocomb referenced this issue in jhollingworth/bootstrap-wysihtml5 September 24, 2012
Closed

Auto resize #113

brainztorm

Hi, love to have this feature too

I see that you plan to add auto-resize for V0.4 … great feature !! :) any release date ?

@tiff … i'm not good at javscript but i have this code to emulate this feature : (btw, i use multiple wysihtml5 whom can be added dynamicaly … if you need some beta tester, don't hesitate ! it would be a pleasure to help you :) )

When a new word is added:

    //resize iframe
    function onNewWord() { 
        var editorHeight = editor.composer.commands.doc.body.clientHeight;
        editor.composer.iframe.style.height = editorHeight+20+"px";
    };

and on load :

    function onLoad() {

            resizeTextFrame();

    }

    function resizeTextFrame(){
            var editorHeight = editor.composer.commands.doc.body.clientHeight;
            var iframeClassName = ".wysihtml5-sandbox."+ textareaid;
            $(iframeClassName).height(editorHeight+20);
    }
Rodrigo zrod referenced this issue in jhollingworth/bootstrap-wysihtml5 October 13, 2012
Open

Textarea not resizable #134

Neville Franks

I have been working on code to resize the wsyihtml5 iframe for a while now. The aforementioned autoresize.js does not working correctly with certain content. Also it's use of a temporary off-screen copy of the content is not ideal, performance wise. And the code is hard to read!

The recommend way to calculate actual content height is to use scrollHeight (autoresize.js doesn't use this).

However with certain content this doesn't give the correct height when the content is inside the <body> element. And different browsers behave differently. For example in Chrome, if the first node is a textnode, scrollHeight is incorrect.

To resolve this issue we need to wrap the content in a <div>. I am doing this outside of wysihtml5, however it is all a bit messy and I have seen a case where the div wrapper was able to be deleted by the user.

So the best way to handle this is for wysihtml5 to remove the contenteditable attribute from the <body>, add a <div> child node to it and make this the contenteditable element. This paves the way for correct auto-resizing and prevents the user from ever deleting the div.

I've had a look through the code and the <body> element is used all over the place. The editor (composer) itself uses this.element as the editable element, but whether changing this to the new div will work properly I have no idea.

So I'd really like to see this change incorporated, as we can then finally solve the resizing issue that many of us want and need.

-Neville

tim peterson

FWIW I would definitely also be interested in whatever comes up in v0.4 for resizing the WYSIHTML5 editor.

I'd like to suggest a small snippet of logic to add to the resizeIframe() proposed by @tiff and @TomoGlavas. This snippet checks to make sure the editor has a certain scrollHeight, e.g., 200px, before resizing the iframe. Without it, the iframe will shrink down to less than 1 line tall until more than 1 line of text exists which is terrible from a UI/UX perspective.

var resizeIframe = function() {
    //check to make sure the scrollHeight is some reasonable height, e.g, 200px, before resizing the <iframe>
  if(editor.composer.element.scrollHeight>200) editor.composer.iframe.style.height = editor.composer.element.scrollHeight + "px";
};

//editor.composer.iframe.style.height='1000';
editor.on("load", function() {
  editor.composer.element.addEventListener("keyup", resizeIframe, false)
  editor.composer.element.addEventListener("blur", resizeIframe, false)
  editor.composer.element.addEventListener("focus", resizeIframe, false)
});

The only other alternative/suggestion I can add to this discussion is to consider using JqueryUI's resizeable(). However, this is a seriously suboptimal solution since 1) its manual resizing; 2) you really can't get JqueryUI component by component (don't want to tack on 100kb just for this).

noferi mickaël

how i done that, using jquery

html :

<div id="editor"><textarea>:)</textarea></div>

css :

#editor > * { width:100%; height:100%; padding:0; margin:0; }

javascript :

var $editor = $("#editor");
var editor = ... init wysihtml5 ...
var ifrm = $(editor.composer.iframe).css({border:0});
var ifrmContent = $(ifrm[0].contentWindow.document);
ifrmContent = ifrmContent.find("html").css({width:"100%",height:"100%",margin:0,padding:0,overflow:"hidden"}).find("body").css({height:"auto",width:"100%",margin:0,padding:0});

function resize(){
 var h = ifrmContent.height();
 $editor.stop().animate({height:h});
}

editor.composer.element.addEventListener("keyup", resize);
editor.on("aftercommand:composer", resize);
window.setTimeout(resize,10);
Dave Houlbrooke

Love this thread so far! Autoresizing is the major missing feature in wysihtml5, as far as I can see.

The examples above pretty much nailed it for me. I found one or two minor things:

  1. I use box-sizing: border-box on textareas, which gets imported by wysihtml5, so when setting the <iframe> height I needed to factor in border width and padding to get the height right.
  2. When you set the height of the <iframe> to the exact scrollHeight of the <body>, you get a weird effect on newlines where all the text in the <body> shunts upwards (on the keydown) before the height increases (on the keyup). The simplest way around this (I've found) is to add a buffer (of 50px) to the <iframe> height, so a newline doesn't cause the <body> to shunt down.
  3. When you backspace and remove lines, the scrollheight isn't calculated correctly (as it includes the CSS height property we set on the previous keypress). As someone mentioned above, the best way to do it on textareas is to clone the textarea, set the height to 1, and calculate the height off the clone. I found the best way to do this in wysihtml5 was to clone the contents of the <iframe> body into a new <div>, get the height of that <div>, remove it again, and set the height of the <iframe> based on the <div>.

The code I ended up using, that covers all these, is below. Note that it doesn't do detection for the box-sizing mode - it just assumes you'd always use border-box, because why wouldn't you! Also note that it's a weird mix of jQuery and native JS, that could probably be cleaned up a bit

var editor = new wysihtml5.Editor('textarea', {
    useLineBreaks: false
});

editor.on('load', function()
{
    var minheight = 150;
    var buffer = 50;

    var padding = parseFloat(editor.composer.iframe.style.paddingTop) + parseFloat(editor.composer.iframe.style.paddingBottom) + parseFloat(editor.composer.iframe.style.borderTopWidth) + parseFloat(editor.composer.iframe.style.borderBottomWidth);
    editor.composer.iframe.style.height = (minheight + padding) + 'px';

    var resize = function() {
        var $div = $('<div>').append($(editor.composer.element).clone().contents()).appendTo(editor.composer.element);
        var scrollheight = $div.get(0).scrollHeight;
        $div.remove();
        if (scrollheight > (minheight - buffer)) editor.composer.iframe.style.height = (scrollheight + buffer + padding) + 'px';
        else editor.composer.iframe.style.height = (minheight + padding) + 'px';
    }

    editor.composer.element.addEventListener('keyup', resize, false)
    editor.composer.element.addEventListener('blur', resize, false)
    editor.composer.element.addEventListener('focus', resize, false)
});
Adam Jahnke

It seems kind of expensive to do a clone() on every keyup, have you seen any performance issues with it? Other than that, I like this approach - I've been having trouble with the backspacing too.

Dave Houlbrooke

I agree. I was a bit worried, but I went with that anyway because I couldn't think of anything more efficient that'd still be accurate. I suppose you could check the keycode and only calculate the height the expensive way if backspace or delete were pressed (or if there was a range selected before the keypress). Seems like more trouble than it's worth though.

I'm seeing no real performance issues on my main machine using 500 paragraphs of ipsum text. I've not tested on mobiles or slightly crapper machines yet, but I can't imagine it's too awful.

There's a slowness generally with wysihtml5 when you remove a newline before an extremely long line of text (> 5KB ish), but the resize code above doesn't make any noticeable difference to that.

noferi mickaël

with overflow hidden on the iframe html we can directly read body height without any clone or visible scrollbar

Dave Houlbrooke

That works when increasing the height, but doesn't work when reducing the height. The problem is that the scrollheight of a <body> tag is always 100% of its frame (in this case, the <iframe>).

The only ways to ascertain the correct scrollheight when shrinking the <iframe> are:

  1. Reduce the height of the <iframe> until the scrollheight of the <body> is higher, then stop.
  2. Clone the contents of the <body> into a <div>, and using that <div>'s scrollheight instead.
  3. Only ever work in a <div> inside the <body>, which would require a complete reworking of wysihtml5.

I went for #2. I imagine #3 is what the team will settle on in the long run when this feature gets baked in, but it's a bit of a ballache! And might mess up some people's stylesheets.

noferi mickaël

i was put height:auto on the iframe body

and it work well, check this demo page http://r043v.github.com/jQuery.scribe/

the only problem i get is the position not stay at top when animate bigger (i need try your 50px more solution)

Neville Franks

@r043v I've tested your code and it works quite well. I've enhanced it to take into account my findings using scrollheight on a div wrapper. I've tested my updates on the latest Chrome and Firefox and on IE9.

I had all sorts of problems when using animate() and have removed that. There is also a slight content jump when Enter etc. is pressed.

        /** Auto-resize the iframe by resizing it's parent wrapper.
         *  ref:  r043v code at https://github.com/xing/wysihtml5/issues/18#issuecomment-11041675
         *  @param editor is wysihtml5 editor instance.
         */
        autoResize: function( editor ){
            var iframe = $(editor.composer.iframe).css({border:0});
            var iframeDocument = $(iframe[0].contentWindow.document);
            var iframeBody = iframeDocument.find("html").css({width:"100%",height:"100%",margin:0,padding:0,overflow:"hidden"})
                                           .find("body").css({height:"auto",width:"100%",margin:0,padding:0});

            function resize(){
                // console.log( '1) iframeBody:', iframeBody, 'iframeBody.height', iframeBody.height(), 'iframeBody.scrollHeight', iframeBody.get(0).scrollHeight );

                // Do an initial height change so we get the correct scrollHeight
                var $editor_wrapper = iframe.parent();
                $editor_wrapper.css( { height: iframeBody.height() } );

                // For Firefox, scrollHeight doesn't include offsetTop for the first child node.
                // Where the firstchild has offsetTop > 0 we need to add it. ex. <body><h3>...
                var $bodyChildren = iframeBody.children();
                var offsetTop = ( $bodyChildren.length && $bodyChildren.get(0).nodeType == 1 ) ? $bodyChildren.get(0).offsetTop : 0;

                // scrollHeight now gives the correct document height, so use it.
                $editor_wrapper.css( { height: iframeBody.get(0).scrollHeight + offsetTop } );

                // For Firefox if the iFrame has no content it's height will be 0, so set it to body.line-height.
                if ( iframeBody.height() < parseInt( iframeBody.css('line-height') ) )
                    $editor_wrapper.css( { height: parseInt( iframeBody.css('line-height') ) } );

                // console.log( '2) iframeBody:', iframeBody, 'iframeBody.height', iframeBody.height(), 'iframeBody.scrollHeight', iframeBody.get(0).scrollHeight, 'offsetTop', offsetTop, 'iframeBody.line-height', iframeBody.css('line-height') );
            }

            editor.composer.element.addEventListener( "keyup", resize );
            editor.on( "aftercommand:composer", resize );

            resize();    // kick things off
        },

and in editor creation:

                    editor.on( "load", function(){
                        // Init iframe auto height resizing. rem: Only call this after content is loaded.
                        self.autoResize( editor );
                    });

I'm still of the opinion that wysihtml5's should use a <div contenteditable=true> instead of <body> and then the height calc is even simpler. See my earlier post.

noferi mickaël

what type of content need this addition ?

Neville Franks

@r043v Please read the comments in my code, they should explain the issues it addresses. In addition if the first node is a text node there was a problem.

Gabriel Engel

I'm trying o implement @nevf sollution - rewritten in pure JS - with a few changes.

Commit:
gabrielengel/wysihtml5@eca6331

Important changes:

1) It's possible not to use the autoResize:
gabrielengel/wysihtml5@eca6331#L0R45

2) Avoid default WysiHtml5's blur & focus reset height:
gabrielengel/wysihtml5@eca6331#L1R165

Pending:
1) Firefox compatibility - I had some issues with childNodes method. In Chrome it returns all elements, even if plain text, Ff doesn't.
2) Test in IE

Any feedback will be appreciated :)

Gabriel Engel

Still had no luck in fixing it to work with Firefox.

I am having a strange dispairity between the iframe's body size while running a test, will take some more time on that.

Released a minified working version for Chrome here:
https://gist.github.com/4345332

Fiddle example:
http://jsfiddle.net/gabito/jnSPf/

Gabriel Engel

Hey, just to update. I'm working on a new approach that seems tons of times easier than what we were doing. I'm encapsulating all the editor's content in a container and letting the browser tell us what is it's final height...

Sounds pretty obvious, no visible conflicts and will allow us to have "auto-resize-down".

ASAP will send a sample!

Pablo Villalba

One of the problems I had when I attempted to write it was adding images, that would resize the container after they loaded and made things harder.

Neville Franks

@gabrielengel My earlier post mentioned than moving the contenteditable attribute from the body to a new div container would indeed simplify this.

Gabriel Engel

@micho Seems that once the image was loaded, this technique will work properly:

Screen Shot 2013-01-04 at 10 24 45

@nevf not sure how/where to change this, we should check with xing people. I see your point and could be handy indeed.

I am struggling to observe the composer element for keydown/keypress events. Did someone work with that before?

Gabriel Engel

Good news :)

Seems that this logic works! The resize itself is working very well under Firefox and Chrome on a Mac.
Now I'm still trying to attach events correctly.

Please, have a look: http://jsfiddle.net/gabito/jnSPf/2/

What works and doesnt:

Chrome:

  • Resizes on: press-enter, blur, focus, load, editor-command (like bold),

Firefox:

  • Resizes on: editor-command, load (very important for the image fix),
  • Doesn't resize on: blur, focus, press-enter

Both:

  • still need to resize on press-delete or press-backspace.

This is due to the assignment of events, which today is like this: https://gist.github.com/4452796

I'm installing IE VMs to test here, but if anyone has the chance to open that jsfiddle on other browsers, I would appreciate :)

Current version (unminified): https://gist.github.com/raw/4452703/f7512ab0b0c097f8d08a63dcfc8d8e3f24274dae/wysihtml5_autoresize.js

Cheers!

Pablo Villalba

@gabrielengel nice job with the jsfiddle. I'm testing in Chrome 23 and found the following issues:

  • Pasting text with cmd+v (for example, the colores source code from your own jsfiddle) doesn't resize the screen.
  • The textarea doesn't shrink after growing.

Looks awesome so far!

jezell

First day trying out the editor, but immediately ran into this problem. Put together something with these ideas that works without cloning and with some other behavior quirks addressed:

https://gist.github.com/4498389

The trick is to edit a div inside the body of the iframe instead of making the body the area being edited. Unlike the body, the div height will be correctly recalculated without needing to clone the contents into another div. Also needed to disable some of the auto copy of styles when auto size is turned on.

Pass autoSize: true in config to enable.

Buffer height is being fixed at 35 right now because that's what my content uses. Should probably be configurable or calculated.

Gabriel Engel

Hi @jezell! How did you implement the div wrapper? Or you have to declare it every time you instantiate?

Looks like a pretty clean code :+1:

Gabriel Engel

Bingo! Found the missing links:
editor.on("newword:composer", resize);
editor.on("paste", resize);

@jezell, I've stolen a bit of your code too, let's get to a conclusion, merge, test and try a pull request :)

Will send a fiddle again in a few minutes

Gabriel Engel

Fiddle: http://jsfiddle.net/gabito/jnSPf/5/
Unminified source: https://gist.github.com/raw/4452703/c60d871bf4b9c253dcfca0cefea4a6411b94aa0c/wysihtml5_autoresize.js
Observing: https://gist.github.com/4452796

  • Paste works;
  • Undo works;
  • Shrink with backspace/delete works (only Chrome);
  • Focus/Blur resize now works on Firefox too;
Joel

Great addition gabrielengel. Haven't run into any issues with it so far though will certainly be doing some extensive testing later. What would be lovely would be the ability to use something like:

editor.on('resize:editor', myfunction);

... to actually be able to adjust the rest of the DOM accordingly when the editor is resized.

Gabriel Engel

@LooseRoots sounds good, I will look into it later :)

Gabriel Engel

Still did not work on @LooseRoots request, will try to do this week.

Meanwhile, can I make a pull request for this changes? cc @tiff

Aleš

How about max height..

veesahni

@gabrielengel pressing enter at the end of the content seems to add one line of space too much.. as a result, typing anything after hitting enter at the end results in the box getting shrunk.

See fiddle: http://jsfiddle.net/GU4XV/1/

The fix is to change how &nbsp; is inserted in getWholeHeight():

  function getWholeHeight(data, firstNode){
    // Text element, wrap up in a paragraph to get height.
    if(data == "") {
      data = "&nbsp;"
    }
    var content = '<div>'+ data +'</div>';
    var node = firstNode.insertAdjacentHTML('afterbegin', content);
    var response = getHeight(firstNode.firstElementChild);

    // Remove element not to affect editing.
    firstNode.removeChild(firstNode.firstElementChild);
    return response;
  }

Gabriel Engel

Hi veeshani, I still didn't test your code. Will try to do over the wkend.

Adding the nbps won't add an extra character to every new paragraph?

veesahni

@gabrielengel the old code was already adding nbsp:

var content = '<div>'+ data +' &nbsp;</div>';

From my testing, it appears this is to ensure that there is always at least 1 line (otherwise the resize() results in the iframe being smaller than the cursor). My modification basically optimizes for this specific case instead of always adding &nbsp;

James Burke

Have you guys tried this in Chrome with Skype installed? (specifically Skype Click-to-call plugin). It completely kills the browser, as well as giving bad results (i.e. incorrect heights). I'm guessing it's because there's content being added, updated and removed to the dom very often, so Skype is probably trying to analyse this each time.

Disabling the plugin solves the problem, but since Skype + Chrome are very common, it's quite a problem.

Matt De Leon

Folks, I put together a little jQuery plugin to handle resizing wysihtml5 editors. You can find it at https://github.com/smidwap/wysihtml5_size_matters/. I've been using it for several successful weeks on Lesson.ly (www.lesson.ly)

I'm not sure it's the responsibility of the wysihtml5 to include auto-resizing capabilities. There are several ways to solve the problem, and the solution may need to be tweaked to cover all use cases. So I think it makes sense to work on the problem in a separate project.

Please give it a try and report any issues you find.

Rich Jones

Everybody in this thread is awesome. @smidwap I'm trying out your code now, will report back with any issues.

Dylan C. Kendal

You can do this in css3:

iframe { 
  resize: both;
}

:)

Matt De Leon

@Dkendal That won't autosize the content area, only allow the user to expand the text editor. Not what we're after.

Dominik Zborowski

Seems @smidwap is best for now, works great!

ARH3
ARH3 commented July 19, 2013

Thanks @smidwap I just implemented your plugin and it works great! For people who want even simpler code for the implementation, I did it this way:

    $('#fancy-textarea').wysihtml5();
    $('iframe.wysihtml5-sandbox').wysihtml5_size_matters();

The "iframe.wysihtml5-sandbox" selector, as far as I can tell, is part of every single wysihtml5-enabled textarea, so it will make them all expandable. Wahoo!

Matt De Leon

@ARH3 thanks for the kind words. That might work when using the wysihtml5 jQuery plugin, but you need to be sure that the editor is loaded into the DOM before calling wysihtml5_size_matters. In other words, `iframe.wysihtml5-sandbox' may not exist yet...maybe the jQuery plugin makes the load synchronous though.

ARH3
ARH3 commented July 19, 2013

Right - so to clarify I DID use the wysihtml5 jQuery plugin (also uses bootstrap, see here) and wrapped that in a jQuery document.ready function:

$(document).ready(function() {
     $('#fancy-textarea').wysihtml5();
     $('iframe.wysihtml5-sandbox').wysihtml5_size_matters();
});

All working together very smoothly!

Brett Jones

@smidwap thanks so much for wysihtml5_size_matters! I used it to replace a horrible, horrible hack which previously attempted (largely unsuccessfully and by resorting to intervals) to do the same thing. Killer!

Kurt Funai

@smidwap Thank you again - exactly what I needed in this case.

Joe Johnston

Here's a working solution for auto-resizing that doesn't require any modifications to wysihtml5.

It seems to be handling image inserting, pasting, and deleting pretty well. Please let me know if you find any edge cases or bugs. I have a few production sites I'd like to use this in if it passes browser tests.

Here's the relevant commit...
simple10/bootstrap-wysihtml5-sass@eb5ab6f

I haven't tested it in all browsers yet, but it should be 90% of the way there. I hope. ;-)

Neville Franks

The vertical scrollbar in the editor keeps flashing on & off when the resize occurs. This is on the current Chrome in Win8.

Joe Johnston

@nerf The flashing is in part due to the debouncer delay. The scrollbar appears as normal while the user types and the resizing happens when there's a delay. The flashing is not as noticeable on OSX. Maybe we can just hide the scrollbars. I'll have to do some compatibility testing and post a fix tomorrow.

Martijn Lafeber

@smidwap do you have any idea why your plugin doesn't work in IE (all versions?) It works fantastic in normal browsers though.

Matt De Leon
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.